在开发项目的过程中,我们经常会选择Servlet 2.5。这时,我们知道:要使Servlet对象正常的运行,需要进行适当的配置,以告知Web容器哪一个请求调用哪一个servlet对象处理。Servlet的配置包含在web.xml文件中,两步实现:
(一)声明Servlet对象
<servlet-name>元素用于指定Servlet的名称,该名称可以自定义;
<servlet-class>元素用于指定Servlet对象的完整位置,包含Servlet对象的包名与类名。
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.xiaoxiao.TestServlet</servlet-class>
</servlet>
(二)映射Servlet
<servlet-name>元素与<servlet>标签中的<servlet-name>元素相对应;
<url-pattern>元素用于映射访问URL。
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/TestServlet</url-pattern>
</servlet-mapping>
但在Servlet 3.0中,因为其新特性【新增注释】,我们就不需再web.xml文件中对Servlet进行配置。让我们一起来了解一下Servlet 3.0的三个重要的特性:
- 新增注释
- 对文件上传的支持
- 异步处理
一、新增注释
通过使用注释就无须在web.xml文件中对Servlet或者过滤器进行配置。Servlet 3.0新增的注释有@WebServlet、@WebFilter、@WebListener、@WebInitParam等。
1.1 @WebServlet
@WebServlet 注释定义在Servlet的类声明之前,用于定义Servlet组件。使用该注释,就无须在web.xml文件中对Servlet进行配置。@WebServlet注释包含很多属性,如下所示:
属性名 | 类型 | 描述 |
---|---|---|
name | String | 指定Servlet的name属性,等价于<servlet-name> 。如果没有显式指定,则该Servlet的取值即为类的全限定名 |
value | String[] | 该属性等价于urlPatterns属性。两个属性不能同时使用 |
urlPatterns | String[] | 指定一组Servlet的URL匹配模式,等价于<url-pattern>标签 |
loadOnStartup | int | 指定Servlet的加载顺序,等价于<load-on-startup>标签 |
initParams | WebInitParam[] | 指定一组Servlet初始化参数,等价于<init-param>标签 |
asyncSupported | boolean | 声明Servlet是否支持异步操作模式,等价于<async-supported>标签 |
description | String | 该Servlet的描述信息,等价于<description>标签 |
displayName | String | 该Servlet的显示名,通常配合工具使用,等价于<display-name>标签 |
举个例子:
@WebServlet(name="TestServlet",urlPatterns="/TestServlet")
1.2 @WebFilter
@WebFilter注释用于声明过滤器,该注解将会在部署时被容器处理,容器根据具体的属性配置将相应的类部署为过滤器。具体属性如下:
属性名 | 类型 | 描述 |
---|---|---|
filterName | String | 指定过滤器的name属性,等价于<filter-name> |
value | String[] | 该属性等价于urlPatterns属性,两个属性不能同时使用 |
urlPatterns | String[] | 指定一组过滤器的URL匹配模式,等价于<url-pattern>标签 |
servletNames | String[] | 指定过滤器将应用于哪些Servlet,是@WebServlet中的name属性的取值,或者是web.xml文件中<servelt-name>的取值 |
initParams | WebInitParam[] | 指定一组Servlet初始化参数,等价于<init-param>标签 |
asyncSupported | boolean | 声明Servlet是否支持异步操作模式,等价于<async-supported>标签 |
description | String | 该Servlet的描述信息,等价于<description>标签 |
displayName | String | 该过滤器的显示名,通常配合工具使用,等价于<display-name>标签 |
dispatcherTypes | DispatcherType | 指定过滤器的转发模式。具体取值包括ASYNC、ERROR、FORWORD、INCLUDE和REQUEST |
举个例子:创建过滤器,并使用@WebFilter注释进行配置。代码如下:
@WebFilter(filterName="char",urlPatterns="/*")
public class CharFilter implements Filter{
...//省略了过滤器中间的代码
}
使用@WebFilter注释,等价于web.xml文件中进行如下配置:
<filter>
<filter-name>char</filter-name>
<filter-class>CharFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>char</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.3 @WebListener
该注释用于声明监听器,还可以用于充当给定Web应用上下文中各种Web应用事件的监听器的类。可以使用@WebListener来标注一个实现ServletContextListener、ServletContextAttributeListener、ServletRequestListener、ServletRequestAttributeListener、HttpSessionListener和HttpSessionAttributeListener的类。@WebListener注释有一个value属性,该属性为可选属性,用于描述监听器信息。使用该注释就不需要在web.xml文件中配置<listener>标签了。
举个例子:创建监听器,代码如下:
@WebListener("This is only a demo listener")
public class MyContentListener implements ServletContextListener{
...//省略了监听器中间的代码
}
1.4 @WebInitParam
该注释等价于web.xml文件中的<servlet>和<filter>的<init-param>子标签,该注释通常不单独使用,而是配合@WebServlet和 @WebFilter使用。它的作用是为Servlet或者过滤器指定初始化参数。@WebInitParam注释包含了一些常用属性,具体如下:
属性名 | 类型 | 是否可选 | 描述 |
---|---|---|---|
name | String | 否 | 指定参数的名字,等价于<param-name> |
value | String | 否 | 指定参数的值,等价于<param-value> |
description | String | 是 | 关于参数的描述,等价于<description> |
举个例子:应用@WebInitParam注释配置初始化参数,代码如下:
@WebServlet(urlPatterns = {"/test"},name="TestServlet"
initParams = {@WebInitParam(name="username",value="tom")}
)
public class TestServlet extends HttpServlet{...}
与上面代码等价的web.xml文件的配置如下:
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.xiaoxiao.TestServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>tom<param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
二、对文件上传的支持
实现文件上传需要以下两项内容:
- 需要添加@MultipartConfig注释。
- 从request对象中获取Part文件对象。
@MultipartConfig注释需要标注在@WebServlet注释之上,常用属性如下:
属性名 | 类型 | 是否可选 | 描述 |
---|---|---|---|
fileSizeThreshold | int | 否 | 当数据量大于该值时,内容将被写入文件 |
location | String | 否 | 存放生成的文件地址 |
maxFileSize | Long | 是 | 允许上传的文件最大值,默认值为-1,表示没有限制 |
maxRequestSize | Long | 是 | 针对该multipart/form-data请求的最大数量,默认值为-1,表示没有限制 |
除此之外,还需要两个重要的方法:
- Part getPart(String name)
- Collection<Part> getParts()
name参数表示请求的name文件。
getParts()方法可获取请求中的所有文件。上传文件用javax.servlet.http.Part对象来表示。
Part接口提供了处理文件的简易方法,如write()、delete()等。
三、异步处理
- 在Servlet 3.0之前,一个Servlet的工作流程为:Servlet首先接收到请求后,需要对请求携带的数据进行一些预处理。接着调用业务接口的某些方法,以完成业务处理。最后根据处理的结果提交响应,这样,Servlet线程结束。在此过程中,如果任何一个任务没有结束,Servlet线程就处于阻塞状态,直到业务方法执行完毕。但这样对于较大的应用,容易造成程序的性能降低。
- 通过使用Servlet 3.0的异步处理机制可以将之前的Servlet处理流程调整为以下过程:首先,Servlet接收到请求之后,需要对请求携带的数据进行一些预处理;接着Servlet线程将请求转交给一个异步线程来执行业务处理,线程本身返回容器,此时Servlet还没有生成响应数据,异步线程处理完业务后,可以直接生成响应数据,或者将请求继续转发给其他Servlet。这样,Servlet线程不再是一直处于阻塞状态以等待业务逻辑的处理,而是启动异步之后可以立即返回。
- 异步处理机制可以应用于Servlet和过滤器两种组件,在默认情况下并没有开启异步处理特性。如果使用该属性,只需将asyncSupported属性的属性值设置为true。以@WebFilter为例,其配置方式如下所示:
@WebFilter(urlPatterns="/myFilter",asyncSupported=true)
public class DemoFilter implements Filter{
...//省略了过滤器实现代码
}
- 在web.xml文件中配置异步处理,增加<async-supported>子标签:
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.xiaoxiao.TestServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>