Servlet3.0新特性

Servlet3.0新特性

1、注解代替配置文件

需要注意的是,如果使用Servlet3.0版本的话:首先Tomcat服务器必须使用7.0版本以上的(老版本不提供3.0版本),其次Eclipse创建Web工程时选择3.0版本。

Servlet3.0版本允许使用注解方式来替代web.xml文件中配置Servlet、Filter和Listener的信息,首先回忆一下web.xml文件是如何配置Servlet、Filter和Listener的:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	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_3_0.xsd">
  <!-- 配置Servlet -->
  <servlet>
    <servlet-name>ServletTest</servlet-name>
    <servlet-class>app.java.servlet.ServletTest</servlet-class>
    <init-param>
    	<param-name>longestory</param-name>
    	<param-value>你好</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletTest</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <!-- 配置Filter -->
  <filter>
  	<filter-name>FilterTest</filter-name>
  	<filter-class>app.java.servlet.FilterTest</filter-class>
  	<init-param>
    	<param-name>longestory</param-name>
    	<param-value>你好</param-value>
    </init-param>
  </filter>
  <filter-mapping>
  	<filter-name>FilterTest</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  <!-- 配置Listener -->
  <listener>
  	<listener-class>app.java.servlet.ListenerTest</listener-class>
  </listener>
</web-app>
 

使用注解替代web.xml文件配置Servlet。

 

@WebServlet(urlPatterns="/*",initParams={@WebInitParam(name="longestory",value="你好")},loadOnStartup=0)
public class ServletTest extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		super.doGet(req, resp);
	}
}

使用注解替代web.xml文件配置Filter

 

 

@WebFilter(urlPatterns="/*",initParams={@WebInitParam(name="longestory",value="你好")})
public class FilterTest implements Filter {
	@Override
	public void init(FilterConfig arg0) throws ServletException {}
	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
	}
	@Override
	public void destroy() {}
}
 

 

使用注解替代web.xml文件配置Listener

 

@WebListener
public class ListenerTest implements HttpSessionListener {
	@Override
	public void sessionCreated(HttpSessionEvent arg0) {}
	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {}
}

TestServlet:

 

 

package app.java.servlet;

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

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

/*
 * <servlet>
 * 	<servlet-name></servlet-name>
 * 	<servlet-class></servlet-class>
 * 	<init-param>
 * 		<param-name></param-name>
 * 		<param-value></param-value>
 * 	</init-param>
 * 	<load-on-startup>0-9</load-on-startup>
 * </servlet>
 * <servlet-mapping>
 *	<servlet-name></servlet-name>
 *	<url-pattern></url-pattern>
 * </servlet-mapping>
 */
/*@WebServlet(
	name="TestServlet",
	urlPatterns={"/test","/atest"},
	initParams={@WebInitParam(name="hcx",value="www.hcx.com")},
	loadOnStartup=0
)*/
public class TestServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		
	}

}
 

 

TestListener:

 

package hcx.java.servlet;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/*
 * <listener>
 * 	<listener-class></listener-class>
 * <listener>
 */
//@WebListener
public class TestListener implements HttpSessionListener {

	@Override
	public void sessionCreated(HttpSessionEvent arg0) {
		
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
		
	}

}
 

 

TestFilter:

 

package hcx.java.servlet;

import java.io.IOException;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
/*
 * <filter>
 * 	<filter-name></filter-name>
 * 	<filter-class></filter-class>
 * 	<init-param>
 * 		<param-name></param-name>
 * 		<param-value></param-value>
 * 	</init-param>
 * </filter>
 * <filter-mapping>
 *	<filter-name></filter-name>
 *	<url-pattern></url-pattern>
 * </filter-mapping>
 */
/*@WebFilter(
	urlPatterns={"/*"},
	initParams={@WebInitParam(name="",value="")},
	servletNames={"/test"},
	dispatcherTypes={DispatcherType.REQUEST,DispatcherType.FORWARD}
)*/
public class TestFilter implements Filter {

	@Override
	public void destroy() {
		
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		
	}

}
 

 

2、使用servlet实现文件上传

 * Servlet实现文件上传
     * @MultipartConfig
       @MultipartConfig(
maxFileSize=1024*1024*3, // 设置上传单个文件大小
maxRequestSize=1024*1024*10, // 设置上传总大小
fileSizeThreshold=1024*1024*3, // 设置缓存大小
location="WEB-INF/tmp" // 设置文件上传的临时目录
       )
     * 利用Part接口
       * 获取Part接口实例:request.getPart(name)
       * 常用方法:
         * 手动获取上传文件名称:
  String header = part.getHeader("Content-Disposition");
  int index = header.lastIndexOf("filename=\"");
  String filename = header.substring(index+10, header.length()-1);
* getInputStream()方法:获取文件输入流.
* write(保存文件的路径)方法:将上传的文件输入流,写入到指定的目录中.
     * 解决中文乱码:
       request.setCharacterEncoding("utf-8");

Servlet3.0的另一个新特性就是提供了处理文件上传的功能,使用Servlet3.0的内容实现文件上传需要以下几个内容:

Ø  在处理文件上传的Servlet上增加@MultipartConfig注解,表示当前Servlet符合MIME类型的multipart/form-data。

int

fileSizeThreshold
The size threshold after which the file will be written to disk

java.lang.String

location
The directory location where files will be stored

long

maxFileSize
The maximum size allowed for uploaded files.

long

maxRequestSize
The maximum size allowed for multipart/form-data requests

Part接口,表示允许接收MIME类型是multipart/form-data类型的POST请求。

void

delete()
Deletes the underlying storage for a file item, including deleting any associated temporary disk file.

java.lang.String

getContentType()
Gets the content type of this part.

java.lang.String

getHeader(java.lang.String name)
Returns the value of the specified mime header as a String.

java.util.Collection<java.lang.String>

getHeaderNames()
Gets the header names of this Part.

java.util.Collection<java.lang.String>

getHeaders(java.lang.String name)
Gets the values of the Part header with the given name.

java.io.InputStream

getInputStream()
Gets the content of this part as an InputStream

java.lang.String

getName()
Gets the name of this part

long

getSize()
Returns the size of this fille.

void

write(java.lang.String fileName)
A convenience method to write this uploaded item to disk.

利用Servlet3.0实现文件上传的功能,具体实现代码如下:

1.创建一个JSP页面用于文件上传显示:

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  <body>
    <form action="uploadFile" method="post" enctype="multipart/form-data">
    	文件描述:<input type="text" name="filetext"><br>
    	<input type="file" name="upload"><br>
    	<input type="submit" value="上传">
    </form>
  </body>
</html>

 

 

2.创建一个Servlet用于处理文件上传逻辑。

 

@WebServlet(urlPatterns="/uploadFile")
@MultipartConfig(
fileSizeThreshold = 10 * 1024,//缓存大小,当上传的文件超出这个大小时会生成临时文件
location = "/temp",// 存放临时文件的目录
maxFileSize = 5 * 1024,// 单个文件大小限制
maxRequestSize = 10 * 1024// 整个请求大小限制
)
public class UploadFileServlet extends HttpServlet {
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 处理请求中文乱码
		req.setCharacterEncoding("utf-8");
		// 接收上传文件的描述内容
		String filetext = req.getParameter("filetext");
		// 接收上传文件的内容
		Part part = req.getPart("upload");
		// 获取上传文件的真实名称
		String cd = part.getHeader("Content-Disposition");
		int index = cd.indexOf("filename=\"") + 10;
		String filename = cd.substring(index, cd.length() - 1);
		// 读取上传目录的绝对路径
		String path = getServletContext().getRealPath("/upload");
		// 将上传文件进行保存
		part.write(path + "/" + filename);
	}
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}
}
 

 

 

package hcx.java.upload;

import java.io.IOException;
import java.io.InputStream;
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;

@WebServlet(urlPatterns={"/upload"})
@MultipartConfig(
	location="\\WEB-INF\\tmp",		// 设置文件上传的临时目录
	fileSizeThreshold=1024*1024*3,	// 设置缓存大小
	maxFileSize=1024*1024*3,		// 设置上传单个文件大小
	maxRequestSize=1024*1024*10	// 设置上传总大小
)
public class UploadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 如何来处理文件的上传逻辑:Part接口
		request.setCharacterEncoding("utf-8");
		
		/*
		 * 1 如何获取文件上传的普通项?
		 *  * 通过Request对象的getParameter(String name)方法,可以或上传的普通项.
		 *    * name参数:指定客户端页面上传普通项的name属性值.
		 */
		String filetext = request.getParameter("filetext");
		
		/*
		 * 2 如何获取Part接口的实例对象?
		 *  * 通过Request对象的getPart(String name)方法,可以获取Part接口的实例对象.
		 *    * name参数:指定客户端页面上传文件域的name属性值.
		 *  * 通过Part接口的实例对象获取有关文件上传项的名称、文件输入流.
		 *  * Part接口提供的write(filename)方法:
		 *    * 将接收到的文件输入流,写入指定的服务器端的目录中.
		 *    * 参数filename:指定的保存文件的绝对路径.
		 *  * Part接口提供getName()方法:
		 *    * 获取的是上传文件域的name属性值.
		 *    * 并没有获取真实上传的文件名称.
		 *  * 上传的真实文件名称应该是如何获取到的呢?
		 *    * Servlet 3.0完成文件上传功能的诟病.
		 *    * 
		 */
		Part part = request.getPart("upload");
		/*String filename = part.getName();
		System.out.println(filename);*/
		
		/*
		 *  获取上传的真实文件名称:
		 *  Content-Disposition: form-data; name="upload"; filename="readme.txt"
		 */
		String header = part.getHeader("Content-Disposition");
		int index = header.lastIndexOf("filename=\"");
		String filename = header.substring(index+10, header.length()-1);
		
		InputStream in = part.getInputStream();
		String realPath = getServletContext().getRealPath("/WEB-INF/uploads");
		part.write(realPath+"/"+filename);
	}

}
 

 

3、servlet异步处理

所谓异步处理就是指数据发送方发送数据给数据接收方后,不必等待数据接收方作出响应,可以继续发送下一个数据的通信方式。

Servlet3.0版本提供了相关异步处理的功能,具体实现方式如下:

  • 需要使用注解在对应Servlet配置asyncSupported=true,表示当前Servlet支持异步。
  • 通过Request对象的startAsync(Request,Response)方法获取异步上下文对象。
  • 通过异步上下文对象调用start(newRunnable(){})方法开始异步处理,Runnable类的run()方法提供具体异步的逻辑代码。

* 实现异步的步骤:
       * 需要使用注解在对应Servlet配置asyncSupported=true,表示当前Servlet支持异步.
       * 通过Request对象的startAsync(Request, Response)方法获取异步上下文对象.
       * 通过异步上下文对象调用start(new Runnable(){})方法开始异步处理,
         Runnable类的run()方法提供具体异步的逻辑代码.
     * 注意:
       * 目前实际情况,实现异步交互的效果,基本上都是Ajax实现.

根据上述步骤,通过一个代码实例演示。
 
@WebServlet(urlPatterns="/async",asyncSupported=true)
public class AsyncServlet extends HttpServlet {
@Override
	protected void doGet(HttpServletRequest req, final HttpServletResponse resp)
			throws ServletException, IOException {
		// 设置响应类型及编码格式
		resp.setContentType("text/html;charset=utf-8");
		resp.getWriter().print("马上开始:<br/>");
		// 刷新缓冲区
		resp.getWriter().flush();
		// 获取异步上下文对象
		final AsyncContext ac = req.startAsync(req, resp);
		// 开始异步处理
		ac.start(new Runnable() {
			@Override
			public void run() {
				try {
					for (char ch = 'A'; ch <= 'Z'; ch++) {
						resp.getWriter().print(ch);
						resp.getWriter().flush();
						Thread.sleep(250);
					}
					// 表示异步处理完毕
					ac.complete();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		});
	}
}
 
 
AsyncServlet
package hcx.java.async;

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

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns={"/async"},asyncSupported=true)
public class AsyncServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, final HttpServletResponse response)
			throws ServletException, IOException {

		// 设置响应类型及编码格式
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().print("马上开始:<br/>");
		// 刷新缓冲区
		response.getWriter().flush();
		
		final AsyncContext context = request.startAsync(request, response);
		
		context.start(new Runnable() {
			
			@Override
			public void run() {
				try {
					for (char ch = 'A'; ch <= 'Z'; ch++) {
						response.getWriter().print(ch);
						response.getWriter().flush();
						Thread.sleep(250);
					}
					// 表示异步处理完毕
					context.complete();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		});
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}

 

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值