A Java Web Application Without a web.xml – 一个没有web.xml的Java网络应用程序

最后修改: 2019年 3月 16日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’re creating a Java web application using Servlet 3.0+.

在本教程中,我们将使用Servlet 3.0+创建一个Java Web应用程序。

We’ll take a look at three annotations – @WebServlet, @WebFilter, and @WebListener – that can help us nix our web.xml files.

我们将看看三个注解–@WebServlet@WebFilter@WebListener–它们可以帮助我们解决web.xml文件。

2. The Maven Dependency

2.Maven的依赖性

In order to use these new annotations, we need to include the javax.servlet-api dependency:

为了使用这些新的注释,我们需要包括javax.servlet-api依赖性。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

3. XML Based Configuration

3.基于XML的配置

Before Servlet 3.0, we’d configure a Java web application in a web.xml file:

在Servlet 3.0之前,我们会在web.xml文件中配置一个Java Web应用程序。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">
    <listener>
        <listener-class>com.baeldung.servlets3.web.listeners.RequestListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>uppercaseServlet</servlet-name>
        <servlet-class>com.baeldung.servlets3.web.servlets.UppercaseServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>uppercaseServlet</servlet-name>
        <url-pattern>/uppercase</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>emptyParamFilter</filter-name>
        <filter-class>com.baeldung.servlets3.web.filters.EmptyParamFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>emptyParamFilter</filter-name>
        <url-pattern>/uppercase</url-pattern>
    </filter-mapping>
</web-app>

Let’s start replacing each configuration section with the respective annotations introduced in Servlet 3.0.

让我们开始用Servlet 3.0中引入的各自的注释来替换每个配置部分。

4. Servlets

4.servlets

JEE 6 shipped with Servlet 3.0 which enables us to use annotations for servlet definitions, minimizing the use of a web.xml file for a web application.

JEE 6配备了Servlet 3.0,它使我们能够为Servlet定义使用注解,最大限度地减少Web应用对web.xml文件的使用。

For example, we can define a servlet and expose it with the @WebServlet annotation

例如,我们可以定义一个servlet,并用@WebServlet注解将其公开

Let’s define one servlet for the URL pattern /uppercase. It will transform the value of the input request parameter to uppercase:

让我们为URL模式/uppercase定义一个Servlet。它将把 input请求参数的值转换成大写字母。

@WebServlet(urlPatterns = "/uppercase", name = "uppercaseServlet")
public class UppercaseServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws IOException {
        String inputString = request.getParameter("input").toUpperCase();

        PrintWriter out = response.getWriter();
        out.println(inputString);
    }
}

Note that we defined a name for the servlet (uppercaseServlet) that we can now reference. We’ll make use of this in the next section.

注意,我们为Servlet定义了一个名字(uppercaseServlet),我们现在可以引用这个名字。我们将在下一节中使用这个名字。

With the @WebServlet annotation, we’re replacing the servlet and servlet-mapping sections from the web.xml file.

通过@WebServlet注解,我们要替换servletservlet-mapping部分,从web.xml文件。

5. Filters

5.过滤器

A Filter is an object used to intercept requests or responses, performing pre- or post-processing tasks.

Filter是一个用于拦截请求或响应的对象,执行预处理或后处理任务。

We can define a filter with the @WebFilter annotation.

我们可以用@WebFilter注解来定义一个过滤器。

Let’s create a filter to check if the input request parameter is present:

让我们创建一个过滤器来检查input请求参数是否存在。

@WebFilter(urlPatterns = "/uppercase")
public class EmptyParamFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {
        String inputString = servletRequest.getParameter("input");

        if (inputString != null && inputString.matches("[A-Za-z0-9]+")) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            servletResponse.getWriter().println("Missing input parameter");
        }
    }

    // implementations for other methods
}

With the @WebFilter annotation, we’re replacing the filter and filter-mapping sections from the web.xml file.

通过@WebFilter注解,我们要替换filterfilter-mapping部分,从web.xml文件。

6. Listeners

6.听众

We’ll often need to trigger actions based on certain events. This is where listeners come to the rescue. These objects will listen for an event and execute the behavior we specify.

我们经常需要根据某些事件来触发行动。这就是监听器的作用。这些对象将监听一个事件并执行我们指定的行为。

Like previously, we can define a listener with the @WebListener annotation.

与之前一样,我们可以用@WebListener注解来定义一个监听器。

Let’s create a listener that counts each time we perform a request to the server. We’ll implement ServletRequestListener, listening for ServletRequestEvents:

让我们创建一个监听器,在我们每次向服务器执行请求时进行计数。我们将实现ServletRequestListener,监听ServletRequestEvents。

@WebListener
public class RequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent event) {
        HttpServletRequest request = (HttpServletRequest)event.getServletRequest();
        if (!request.getServletPath().equals("/counter")) {
            ServletContext context = event.getServletContext();
            context.setAttribute("counter", (int) context.getAttribute("counter") + 1);
        }
    }

    // implementations for other methods
}

Note that we are excluding the requests to the URL pattern /counter.

注意,我们排除了对URL模式/counter的请求。

With the @WebListener annotation, we’re replacing the listener section from the web.xml file.

通过@WebListener注解,我们要从web.xml文件中替换listener部分。

7. Build and Run

7.建立和运行

For those following along, note that for testing, there’s a second servlet we’ve added for the /counter endpoint that simply returns the counter servlet context attribute.

对于那些跟随者,请注意,为了测试,我们为/counter端点添加了第二个servlet,它只是返回counter servlet上下文属性。

So, let’s use Tomcat as the application server.

因此,让我们使用Tomcat作为应用服务器。

If we are using a version of maven-war-plugin prior to 3.1.0, we’ll need to set the property failOnMissingWebXml to false.

如果我们使用的是3.1.0之前的maven-war-plugin版本,我们需要将failOnMissingWebXml属性设为false

Now, we can deploy our .war file to Tomcat, and access to our servlets.

现在,我们可以将我们的.war文件部署到Tomcat,并访问我们的Servlets。

Let’s try out our /uppercase endpoint:

让我们试试我们的/uppercase端点。

curl http://localhost:8080/spring-mvc-java/uppercase?input=texttouppercase

TEXTTOUPPERCASE

And we should also see how our error handling looks:

我们还应该看看我们的错误处理是什么样子。

curl http://localhost:8080/spring-mvc-java/uppercase

Missing input parameter

And finally, a quick test of our listener:

最后,对我们的听众进行一次快速测试。

curl http://localhost:8080/spring-mvc-java/counter

Request counter: 2

8. XML Still Needed

8.仍然需要XML

Even, with all the features introduced in Servlet 3.0, there are some use cases where we’ll still need a web.xml file, among them:

即使,在Servlet 3.0中引入了所有的功能,在一些使用情况下,我们仍然需要一个web.xml文件,其中。

  • We can’t define the filter order with annotations – we still need the <filter-mapping> section if we have multiple filters that we need to be applied in a particular order
  • To define a session timeout, we still need to use the <session-config> section
  • We still need the <security-role> element for container-based authorization
  • And to specify welcome files, we’ll still need a <welcome-file-list> section

Or, Servlet 3.0 also introduced some programmatic support via ServletContainerInitializer, too, which can also fill in some of these gaps.

或者,Servlet 3.0也通过ServletContainerInitializer引入了一些编程支持,这也可以填补其中的一些空白。

9. Conclusion

9.结语

In this tutorial, we configured a Java web Application without using the web.xml file by exercising the equivalent annotations.

在本教程中,我们通过行使同等的注释,在不使用web.xml文件的情况下配置了一个Java Web应用程序。

As always, the source code for this tutorial can be found on GitHub. Additionally, an application using the traditional web.xml file can also be found on GitHub.

一如既往,本教程的源代码可以在GitHub上找到。此外,在GitHub上也可以找到一个使用传统web.xml文件的应用程序。

For a Spring-based approach, head over to our tutorial web.xml vs. Initializer with Spring.

对于基于Spring的方法,请前往我们的教程web.xml vs. Initializer with Spring.