Servlet3.0新特性

Servlet3.0新特性

制作人:全心全意

新增注释

新增注释是Servlet3.0中的重大革新之一。通过使用注释就无须再web.xml文件中对Servlet或者过滤器进行配置。Servlet3.0新增的注释有@WebServlet、@WebFilter、@WebListener和@WebInitParam等。

  • @WebServlet

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

属   性   名 类     型 描     述
  name   String 指定Servlet的name属性,等价于<servlet-name>。如果没有显式指定,则该Servlet的取值即为类的全限定名
  value   String[] 该属性等价于urlPattern属性,两个属性不能同时使用
  urlPatterns   String[] 指定一组Servlet的URL匹配模式。等价于<url-pattern>标签
  loadOnStartup   int

指定Servlet的加载顺序,等价于<load-on-startup>标签

  initParams   WebInitParam[] 指定一组Servlet初始化参数,等价于<init-pararn>标签
  asyncSupported   boolean 声明Servlet是否支持异步操作模式,等价于<async-supported>标签
  description   String 该Servlet的描述信息,等价于<description>标签
  displayName   String 该Servlet的显示名,通常配合工具使用,等价于<display-name>标签

Servlet创建对比示例:

@WebServlet(name = "SServlet", urlPatterns = "/SServlet")
public class SServlet extends HttpServlet {
  //省略Servlet中的代码
}

  等价于web.xml中如下配置:

 

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

 

 

  •  @WebFilter

@webFilter注释用于声明过滤器,该注解将会在部署时被容器处理,容器根据具体的属性配置将相应的类部署为过滤器。该属性也包含很多属性,如下表所示。

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

 过滤器创建对比示例:

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

  等价于web.xml中如下配置:

	<filter>
		<filter-name>char</filter-name>
		<filter-class>com.Ma</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>char</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

 

  •  @WebListener

该注释用于声明监听器,还可以用于充当给定Web应用上下文中各种Web应用事件的监听器的类。可以使用@WebListener来标注一个实现ServletContextListener、ServletContextAttributeListener、ServletRequestListener、ServletRequestAttributeListener、HttpSessionListener和HttpSessionAttributeListener的类。@WebListener注释有一个value的属性,该属性为可选属性,用于描述监听器信息。

 声明监听器示例:

@WebListener("This is only a demo listener")
public class Ma {
	public class CharFilter implements ServletContextListener {
            //省略监听器中的代码
	}
}    

 

  • @WebInitParam

该注释等价于web.xml文件中的<servlet>和<filter>的<init-param>子标签,该注释通常不单独使用,而是配合@WebServlet或者@WebFilter使用。它的作用是为Servlet或者过滤器指定初始化参数。@WebInitParam注释包含了一些常用属性,如下表所示。

属  性  名 类     型 是  否  可  选 描     述
  name   String   指定参数的名字,等价于<param-name>
  value   String   指定参数的值,等价于<param-value>
  description   String   关于参数的描述,等价于<description>

 初始化参数对比示例:

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

  等价于web.xml中如下配置:

	<servlet>
		<servlet-name>SimpleServlet</servlet-name>
		<servlet-class>com.SimpleServlet</servlet-class>
		<init-param>
			<param-name>username</param-name>
			<param-value>zhangsan</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>SimpleServlet</servlet-name>
		<url-pattern>/simple</url-pattern>
	</servlet-mapping>

  

 

文件上传

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

  需要添加@MultipartConfig注释

  从request对象中获取Part文件对象

@MultipartConfig注释需要标注在@WebServlet注释之上。其具有的属性如下表所示。

属   性   名 类     型 是  否  可  选 描     述
  fileSizeThreshold     Int 当数据量大于该值时,内容将被写入文件
  location     String 存放生成的文件地址
  maxFileSize     Long 允许上传的文件最大值,默认值为-1,表示没有限制
  maxRequestSize     Long 针对该multipart/form-data请求的最大数量,默认值为-1,表示没有限制

  除了要配置@MultipartConfig注解之外,还需要两个重要的方法,即getPart()与getParts()方法。下面对这两个方法进行详细介绍。

    Part getPart(String name)

    Collection<Part> getParts()

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

文件上传实例:

UploadServlet类:Servlet类,实现文件上传

package com.mingrisoft;

import java.io.IOException;
import javax.servlet.ServletException;
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;

import java.io.PrintWriter;
import javax.servlet.annotation.MultipartConfig;

import org.apache.catalina.core.ApplicationPart;


@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")) {			// 仅处理上传的图像文件
			ApplicationPart ap = (ApplicationPart) p;
			String fname1 = ap.getName();				//获取上传文件名
			System.out.println(fname1);
			int path_idx = fname1.lastIndexOf(":") + 1;		//对上传文件名进行截取
			String fname2 = fname1.substring(path_idx, fname1.length());	
			p.write(path + "/upload/" + fname2);			// 写入 web 项目根路径下的upload文件夹中
			System.out.println(path + "/upload/" + fname2);
			out.write("文件上传成功");							
		}
		else{
			  out.write("请选择图片文件!!!");
		}
	}
}

  

index.jsp页面:放置提交图片文件的文件选择器

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 <form action="UploadServlet" enctype="multipart/form-data" method ="post" >
    选择文件<input type="file" name="file1" id= "file1"/>   
    <input type="submit" name="upload" value="上传" />
 </form>
</body>
</html>

  

异步处理

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

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

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

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

以@WebFilter为例,其配置方法如下所示。

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

  等价于web.xml中如下配置:

	<servlet>
		<servlet-name>CharServlet</servlet-name>
		<servlet-class>com.DemoFilter</servlet-class>
		<async-supported>true</async-supported>
	</servlet>
	<servlet-mapping>
		<servlet-name>CharServlet</servlet-name>
		<url-pattern>/chFilter</url-pattern>
	</servlet-mapping>

  

posted @ 2018-09-29 17:55  全心全意_运维  阅读(240)  评论(0编辑  收藏  举报