Servlet3.0新特性

Servlet 3.0中引入了若干个重要的新特性,例如新增的注释、异步处理、可插型支持等内容。这些内容的添加是Servlet技术逐渐完善的一个体现。

1、新增注释

Servlet 3.0中的重大革新之一。通过使用注释就无需在web.xml文件中对Servlet或者过滤器进行配置。Servlet 3.0新增的注释有@WebServlets、@WebFilter、@WebListener、@WebInitParam等。

1.1 @WebServlet注释

@WebServlet注释定义在Servlet的类声明之前,用于定义Servlet组件。使用该注释,就无须再 web.xml 文件中对Servlet进行配置。@WebServlet注释包含很多属性。

@WebServlet注释主要属性列表:

属性名类型描述
nameString指定Servlet的name属性,等价于<servlet-name>标签。如果没有显示指定,则该Servlet的取值即为类的全限定名。
valueString[]该属性等价于urlPatterns属性。两个属性不能同时使用。
urlPatternsString[]指定一组Servlet的URL匹配模式,等价于<url-pattern>标签。
loadOnStartupint指定Servlet的加载顺序,等价于<load-on-startup>标签。
initParamsWebInitParam[]指定一组Servlet初始化参数,等价于<init-param>标签。
asyncSupportedboolean声明Servlet是否支持异步操作,等价于<async-supported>标签。
smallIconString此Servlet的小图标。
largeIconString此Servlet的大图标。
descriptionString该Servlet的描述信息,等价于<description>标签。
displayNameString该Servlet的显示名,通常配合工具使用,等价于<display-name>标签。

示例:使用Servlet实现用户注册功能。

(1)创建index.jsp页面。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
	<div>请输入注册信息
		<form name="form1" method="post" action="servlet/RegServlet">
			<table border="0" >
				<tr>
					<td>姓名:</td>
					<td><input type="text" name="name"/></td>
				</tr>
				<tr>
					<td>年龄:</td>
					<td><input type=text name="age"/></td>
				</tr>
				<tr>
					<td>性别:</td>
					<td>
						<select name = "sex">
							<option value="男" selected="selected">男</option>
							<option value="女">女</option>
						</select>
					</td>
				</tr>
				<!-- 以下是提交、取消按钮 -->
				<tr>
					<td>
						<input type="submit" value="提交" />
					</td>
					<td>
						<input type="reset" value="取消" />
					</td>
				</tr>
			</table>
		</form>
	</div>
</body>
</html>

(2)创建名为RegServlet的Servlet类。该类继承HttpServlet类,并应用@WebServlet注释,配置Servlet的name属性与urlPatterns属性。

package com.pjb.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户注册Servlet类
 * 
 * @author pan_junbiao
 *
 */
@WebServlet(name = "RegServlet", urlPatterns = "/servlet/RegServlet")
public class RegServlet extends HttpServlet
{

	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		// 设置request的编码
		request.setCharacterEncoding("UTF-8");
		// 获取信息
		String name = request.getParameter("name");
		String age = request.getParameter("age");
		String sex = request.getParameter("sex");

		// 设置response的编码
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html");
		// 获取PrintWriter对象
		PrintWriter out = response.getWriter();
		// 输出信息
		out.println("<HTML>");
		out.println("<HEAD><TITLE>注册信息</TITLE></HEAD>");
		out.println("<BODY>");
		out.println("姓名:" + name + "<br>");
		out.println("年龄:" + age + "<br>");
		out.println("性别:" + sex + "<br>");
		out.println("</BODY>");
		out.println("</HTML>");
		// 释放PrintWriter对象
		out.flush();
		out.close();
	}
}

说明:使用@WebServlet注释,配置Servlet的name属性与urlPatterns属性,如下代码:

@WebServlet(name = "RegServlet", urlPatterns = "/servlet/RegServlet")

这样配置完成后,就不必在 web.xml 文件中配置相应的<servlet>和<servlet-mapping>元素了。与上面的代码等价的 web.xml 文件的配置如下:

<servlet>
  <servlet-name>RegServlet</servlet-name>
  <servlet-class>com.pjb.servlet.RegServlet</servlet-class>
</servlet>
 
<servlet-mapping>
  <servlet-name>RegServlet</servlet-name>
  <url-pattern>/servlet/RegServlet</url-pattern>
</servlet-mapping>

执行结果:

(1)注册页面 index.jsp。

(2)提交注册结果信息。

 

1.2 @WebFilter注释

@WebFilter注释用于声明过滤器,该注释将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。

@WebFilter注释主要属性列表:

属性名类型描述
filterNameString指定过滤器的name属性,等价于<filter-name>标签。
valueString[]该属性等价于urlPatterns属性,但是两者不应该同时使用。
urlPatternsString[]指定一组过滤器的URL匹配模式,等价于<url-pattern>标签。
servletNamesString[]指定过滤器将应用于哪些Servlet,是@WebServlet中的name属性的取值,或者是web.xml文件中的<servlet-name>标签的取值。
initParamsWebInitParam[]指定一组过滤器初始化参数,等价于<init-param>标签。
asyncSupportedboolean声明过滤器是否支持异步操作模式,等价于<async-supported>标签。
descriptionString该过滤器的描述信息,等价于<description>标签。
displayNameString该过滤器的显示名,通常配合工具使用,等价于<display-name>标签。
dispatcherTypesDispatcherType[]指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE 和 REQUEST。

示例:创建过滤器,使用@WebFilter注释进行配置。

@WebFilter(filterName = "char", urlPatterns = "/*")
public class CharFilter implements Filter
{
	// 省略了过滤器中间的代码
}

如此配置之后,就不需要在 web.xml 文件中配置相应的<filter>和<filter-mapping>元素了,容器会在部署时根据指定的属性将该类发布为过滤器。使用@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注释

@WebListener注释用于声明监听器,该注释用于充当给定web应用上下文中各种web应用事件的监听器的类。可以使用@WebListener来标注一个实现:ServletContextListener、ServletContextAttributeListener、ServletRequestListener、ServletRequestAttributeListener、HttpSessionListener、HttpSessionAttributeListener的类。@WebListener注释有一个value的属性,该属性为可选属性,用于描述监听器信息。使用该注释就不需要在 web.xml 文件中配置<listener>标签了。

示例:使用@WebListener注释,创建监听器。

@WebListener("监听器的描述信息")
public class MyContextListener implements ServletContextListener
{
	// 省略了监听器中间的代码
}

这样配置完成后,就不必在 web.xml 文件中配置相应的<listener>元素了。与上面的代码等价的 web.xml 文件的配置如下:

<listener>
	<listener-class>MyContextListener</listener-class>
</listener>

 

1.4 @WebInitParam注释

@WebInitParam注释等价于web.xml文件中的<servlet>和<filter>的<init-param>子标签,该注释通常不单独使用,而是配合@WebServlet或者@WebFilter使用。

@WebInitParam注释主要属性列表:

属性名类型描述
nameString指定参数的名字,等价于<param-name>标签,必填项。
valueString指定参数的值,等价于<param-value>标签,必填项。
descriptionString关于参数的描述,等价于<description>标签,非必填项。

示例:应用@WebInitParam注释配置初始化参数。

package com.pjb.servlet;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

@WebServlet(urlPatterns = { "/simple" }, name = "SimpleServlet", 
initParams = { @WebInitParam(name = "username", value = "pan_junbiao") })
public class SimpleServlet extends HttpServlet
{
	// 省略了Servlet中间的代码
}

这样配置完成后,就不必在 web.xml 文件中配置相应的<servlet>和<servlet-mapping>元素了。与上面的代码等价的 web.xml 文件的配置如下:

<servlet>
	<servlet-name>SimpleServlet</servlet-name>
	<servlet-class>com.pjb.servlet.SimpleServlet</servlet-class>
	<init-param>
		<param-name>username</param-name>
		<param-value>pan_junbiao</param-value>
	</init-param>
</servlet>

<servlet-mapping>
	<servlet-name>SimpleServlet</servlet-name>
	<url-pattern>/simple</url-pattern>
</servlet-mapping>

 

2、对文件上传的支持

在Servlet3.0出现之前,处理文件上传是一件很麻烦的事情,因为要借助第三方组件,例如commons fileupload等。而Servlet3.0出现以后就摆脱了这一问题。使用Servlet3.0可以十分方便的实现文件的上传。实现文件上传需要以下两项内容:

(1)需要添加@MultipartConfig注释。

(2)从request对象中获取Part文件对象。

@MultipartConfig注释需要标注在@WebServlet注释之上。

@MultipartConfig注释主要属性列表:

属性名类型描述
fileSizeThresholdint当数据量大于该值时,内容将被写入文件。
locationString存放生成的文件地址。
maxFileSizelong允许上传的文件最大值。默认值为-1,标识没有限制。
maxRequestSizelong针对该multipart/form-data请求的最大数量,默认值为-1,表示没有限制。

除了要配置@MultipartConfig注释之外,还需要两个重要的方法,即:getPart(String name)与getParts()方法。

Part getPart(String name)

Collection<Part> getParts()

getPart(String name)方法的name参数表示请求的表单的name文件。getParts()方法可获取请求中的所有文件。上传文件用 javax.servlet.http.Part 对象来表示。Part 接口提供了处理文件的简易方法,如:write(String fileName)、delete()等。

示例:应用Servlet实现文件上传。

(1)编写具有上传文件组件的JSP页面。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
	<form action="UploadServlet" enctype="multipart/form-data" method="post">
		选择文件:<input type="file" name="file1" id="file1">
		<input type="submit" name="btnUpload" value="上传" />
	</form>
</body>
</html>

(2)编写处理上传文件的Servlet,在该Servlet中对上传文件进行控制。

package com.pjb.servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * 文件上传Servlet类
 * 
 * @author pan_junbiao
 *
 */
@WebServlet("/UploadServlet")
@MultipartConfig
public class UploadServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		String path = this.getServletContext().getRealPath("/"); // 获取服务器地址
		Part p = request.getPart("file1"); // 获取用户选择的上传文件
		if (p.getContentType().contains("image")) // 仅处理上传的图片文件
		{
			String fname1 = p.getSubmittedFileName(); // 获取上传文件的名称
			String fileName = path + "/upload/" + fname1; // 上传文件的路径和文件名称

			File file = new File(fileName);
			File parentFile = file.getParentFile();
			if (!parentFile.exists()) // 如果文件夹不存在,则创建该文件夹
			{
				parentFile.mkdir();
			}

			p.write(fileName); // 写入文件
			out.write("文件上传成功");

		} else
		{
			out.write("请选择图片文件!");
		}
	}
}

执行结果:

运行本程序,选择上传文件后,如果上传文件是图片文件,点击“上传”按钮后,即可实现文件上传。

 

3、异步处理

异步处理是 Servlet3.0最重要的内容之一。在此之前,一个Servlet的工作流程是:首先,Servlet接收到请求后,需要对请求携带的数据进行一些预处理。接着调用业务接口的某些方法,以完成业务处理。最后,根据处理的结果提交响应,至此,Servlet线程结束。在此过程中,如果任何一个任务没有结束,Servlet线程就处于阻塞转态,直到业务方法执行完毕。对于较大的应用,很容易造成程序性能的降低。

Servlet3.0针对这一问题做了突破性的工作,现在通过使用 Servlet3.0的异步处理机制可以将之前的Servlet处理流程调整为以下过程。首先,Servlet接收到请求之后,可能需要对请求携带的数据进行一些预处理;接着Servlet线程将请求转交给一个异步线程来执行业务处理,线程本身返回至容器,此时Servlet还没有生成响应数据,异步线程处理完业务之后,可以直接生成响应数据,或者将请求继续转发给其它Servlet。这样,Servlet线程不再是一直处于阻塞状态以等待业务逻辑的处理,而是启动异步之后可以立即返回。

异步处理机制可以应用于Servlet和过滤器两种组件,由于异步处理的工作模式与普通工作模式有着本质的区别,在默认情况下,并没有开启异步处理特性,如果希望使用该特性,则必须按如下的方法启用:

3.1 使用asyncSupported属性

@WebServlet和@WebFilter注释提供了asyncSupported属性,默认该属性的取值为false,要启用异步处理支持,只需将该属性设置为true即可。

示例:@WebServlet和@WebFilter注释实现设置异步处理。

@WebFilter(urlPatterns = { "/chFilter" }, asyncSupported = true)
public class DemoFilter implements Filter
{
	// 省略了过滤器实现代码
}

3.2 通过在web.xml文件中配置<async-supported>子标签

如果实现选择在web.xml文件中对Servlet或者过滤器进行配置,可以在Servlet 3.0为<servlet>和<filter>标签增加了<async-supported>子标签,该标签的默认取值为false,要启用异步处理支持,则将其设为true即可。

示例:在web.xml文件中配置异步处理。

<servlet>
	<servlet-name>CharServlet</servlet-name>
	<servlet-class>com.pjb.servlet.CharServlet</servlet-class>
	<async-supported>true</async-supported>
</servlet>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pan_junbiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值