Servlet3.0新特性使用详解
- 可插拔的Web框架
- 几乎所有基于Java的web框架都建立在servlet之上。现今大多数web框架要么通过servlet、要么通过Web.xml插入。利用标注(Annotation)来定义servlet、listener、filter将使之(可插拔)成为可能。程序访问web.xml和动态改变web应用配置是所期望的特性。该JSR将致力于提供把不同web框架无缝地插入到web应用的能力。
- EOD
- 标注——利用标注来作为编程的声明风格。
- web应用零配置是EoD努力方向之一。部署描述符将被用来覆盖配置。
- 范型(generic)——在API中尽可能利用范型。
- 使用其它语言增强可能需要改善API可用性的地方。
- 支持异步和Comet
- 非阻塞输入——从客户端接收数据,即使数据到达缓慢也不会发生阻塞。
- 非阻塞输出——发送数据到客户端,即使客户端或网络很慢也不会发生阻塞。
- 延迟请求处理——Ajax web应用的Comet风格,可以要求一个请求处理被延迟,直到超时或一个事件发生。延迟请求处理对以下情况也很有用:如果远程的/迟缓的资源必须在为该请求服务之前被获得;或者如果访问一个特殊资源,其需要扼杀一些请求以防止太多的并发访问。
- 延迟响应关闭——Ajax web应用的Comet风格,可以要求响应保持打开,以允许当异步事件产生时发送额外的数据。
- 阻塞/非阻塞通知——通知阻塞或非阻塞事件。
- 频道概念——订阅一个频道,以及从该频道获取异步事件的能力。这意味着可以创建、订阅、退订,以及应用一些诸如谁能加入、谁不能加入的安全限制。
- 安全
- login/logout能力。
- 自注册。
- 结合
- 其它
- 支持更好的欢迎文件(welcome file)。
- ServletContextListener排序。
- 容器范围内定义init参数。
- 文件上载——过程侦听——存储中间或最终文件。
- 澄清线程安全问题。
我们下面就看看其中几个特性:
1.可插拔的Web框架,其实就是web.xml中可以又多个子模块的配置文件组成,而各个子模块的配置文件可以放在各个jar包的META-INFO中,这样就实现web应用的模块化。
类似,可以按照配置的顺序指定了web片段的顺序。通过absolute-ordering进行绝对顺序配置,通过每个fragment的order的after和before标签进行相对顺序配置。
- <?xml version="1.0" encoding="GB18030"?>
- <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">
- <absolute-ordering>
- <name>web-fragment1</name>
- <name>web-fragment2</name>
- </absolute-ordering></web-app>
每个fragment1的配置如下:
- <?xml version="1.0" encoding="GB18030"?>
- <web-fragment 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-fragment_3_0.xsd">
- <name>web-fragment1</name>
- <ordering><after>web-fragment1</after><before><others/></before></ordering>
- </web-fragment>
2. servlet3.0的annotation支持
对于原来在web.xml定义的servlet,filter,listener,InitParam都可以通过annotation来配置了,而不需要在web.xml中定义。
@WebFilter
- import java.io.IOException;
- 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;
- //asyncSupported=true 对应filter也需要定义asyncSupported=true
- @WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)
- @WebInitParam(name="a", value="valuea")
- public class My3Filter implements Filter{
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public void doFilter(ServletRequest arg0, ServletResponse arg1,
- FilterChain arg2) throws IOException, ServletException {
- System.out.println("servlet 3 filter");
- arg2.doFilter(arg0, arg1);
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- System.out.println("servlet 3 filter init");
- }
- }
@WebServlet
- import java.io.IOException;
- 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;
- //asyncSupported=true 对应filter也需要定义asyncSupported=true
- @WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)
- @WebInitParam(name="a", value="valuea")
- public class My3Filter implements Filter{
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public void doFilter(ServletRequest arg0, ServletResponse arg1,
- FilterChain arg2) throws IOException, ServletException {
- System.out.println("servlet 3 filter");
- arg2.doFilter(arg0, arg1);
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- System.out.println("servlet 3 filter init");
- }
- }
支持的annotation如下,都可以通过eclipse的提示查到对应的参数配置,
@WebServlet支持的参数有
3. servlet3.0的异步支持
很多时候Servlet要和其他的资源进行互动,例如访问数据库,调用web service。在和这些资源互动的时候,Servlet不得不等待数据返回,然后才能够继续执行。这使得Servlet调用这些资源的时候阻塞。Servlet3.0通过引入异步处理解决了这个问题。异步处理允许线程调用资源的时候不被阻塞,而是直接返回。AsyncContext负责管理从资源来的回应。AsyncContext决定该回应是应该被原来的线程处理还是应该分发给容器中其他的资源。AsyncContext有一些方法如start,dispatch和complete来执行异步处理。
要想使用Servlet3.0的异步处理,我们需要设置@Webservlet和@WebFilter注解的asyncSupport属性。这个属性是布尔值,缺省值是false。
所以,可以在servlet阻塞处理网络,数据库查询等时,可以暂时释放线程资源,处理更多请求,当请求处理完之后重新唤醒线程继续处理原来的请求,达到NIO的效果。
我们看下一个示例
- AsyncContext 可以添加监听器作为异步处理过程中状态的跟踪等
- import java.io.IOException;
- import java.util.Date;
- import javax.servlet.AsyncContext;
- import javax.servlet.AsyncEvent;
- import javax.servlet.AsyncListener;
- import javax.servlet.ServletConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- @WebServlet(asyncSupported=true,name="asyncServlet", urlPatterns="/async")
- public class AsyncServlet extends HttpServlet{
- /**
- *
- */
- private static final long serialVersionUID = 3903580630389463919L;
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- resp.getWriter().write("hello, async test");
- resp.getWriter().println("start:"+new Date()+".<br/>");
- resp.getWriter().flush();
- final AsyncContext async = req.startAsync(req,resp);
- async.setTimeout(3000);
- async.start(new Runnable() {
- @Override
- public void run() {
- ServletRequest request = async.getRequest();
- try {
- Thread.sleep(2000);
- async.getResponse().getWriter().write("aync thread processing");
- async.getResponse().getWriter().flush();
- async.getResponse().getWriter().println("async end:"+new Date()+".<br/>");
- async.getResponse().getWriter().flush();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- });
- async.addListener(new AsyncListener() {
- @Override
- public void onTimeout(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- @Override
- public void onStartAsync(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- @Override
- public void onError(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- @Override
- public void onComplete(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- });
- resp.getWriter().println("end:"+new Date()+".<br/>");
- resp.getWriter().flush();
- }
- }
输出如下: 这里先对线程后面的println先输出,最后在处理输出异步线程输出的内容。
- hello, async teststart?Mon Dec 10 20:23:35 CST 2012.
- end?Mon Dec 10 20:23:35 CST 2012.
- aync thread processingasync end?Mon Dec 10 20:23:37 CST 2012.
这里有个主意点,对于servlet配置了asyncSupported=true,那么对于所有异步经过的filter也需要配置这个参数,否则这里会报错,不支持异步处理。
4.@MultipartConfig 文件上传的支持,以前servlet要处理上传文件一般会使用common file upload组件,现在servlet3.0原生支持了文件上传的处理
location参数指定临时文件存放目录,'
- package com.servlet;
- import java.io.IOException;
- 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(asyncSupported=true,name="upload", urlPatterns="/upload")
- @MultipartConfig(fileSizeThreshold = 10000, maxFileSize = 1000000, maxRequestSize = 1000000, location="E:/logs")
- public class MultiPartServlet3 extends HttpServlet {
- /**
- *
- */
- private static final long serialVersionUID = 7306582588845300635L;
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- Part part = req.getPart("file");
- String value = part.getHeader("content-disposition");
- System.out.println(value);
- String filename = value.substring(value.lastIndexOf("=") + 2,value.length() - 1);
- System.out.println(filename);
- System.out.println(part.getInputStream().toString());
- }
- }
我们写一个文件上传的页面
- <form action="upload" method="post" enctype="multipart/form-data">
- <input type="file" name="file"><br> <input type="submit"
- value="submit">
- </form>
随便上传一个文件,我这边的输出为:
- form-data; name="file"; filename="22.log"
- 22.log
- java.io.ByteArrayInputStream@1bdce67
5.已有API改进,特别是支持动态加载servlet,热部署功能
- HttpServletRequest
- To support the multipart/form-data MIME type, the following methods have been added to the HttpServletRequest interface:
- 为了支持multipart/form-data MIME类型,在HttpServletRequest接口中添加了项目的方法:
- * Iterable<Part> getParts()
- * Part getPart(String name)
- Cookies
- 为了避免一些跨站点攻击,Servlet3.0支持HttpOnly的cookie。HttpOnly cookie不想客户端暴露script代码。Servlet3.0在Cookie类中添加了如下的方法来支持HttpOnly cookie:
- * void setHttpOnly(boolean isHttpOnly)
- * boolean isHttpOnly()
- ServletContext
- 通过在ServletContext中添加下面的方法,Servlet3.0允许Servlet或filter被编程的加入到context中:
- * addServlet(String servletName, String className)
- * addServlet(String servletName, Servlet servlet)
- * addServlet(String servletName, Class<? extends Servlet> servletClass)
- * addFilter(String filterName, String className)
- * addFilter(String filterName, Filter filter)
- * addFilter(String filterName, Class<? extends Filter>filterClass)
- * setInitParameter (String name, String Value)
Servlet3.0新特性使用详解的更多相关文章
- Java基础加强-(注解,动态代理,类加载器,servlet3.0新特性)
1. Annotation注解 1.1. Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annota ...
- JDK19新特性使用详解
前提 JDK19于2022-09-20发布GA版本,本文将会详细介绍JDK19新特性的使用. 新特性列表 新特性列表如下: JPE-405:Record模式(预览功能) JPE-422:JDK移植到L ...
- Servlet3.0新特性
1 Servlet3.0新特性概述 使用要求:MyEclipse10.0或以上版本,发布到Tomcat7.0或以上版本,创建JavaEE6.0应用! Servlete3.0的主要新特性如下三部分: 使 ...
- 【servlet3.0新特性】Annotation注解配置
servlet3.0新特性Servlet3.0引入的若干重要新特性,包括异步处理.新增的注解支持.可插性支持等等,为读者顺利向新版本过渡扫清障碍.Servlet3.0新特性概述Servlet3.0作为 ...
- 【Servlet3.0新特性】第03节_文件上传
这是一个Web Project 首先是web.xml <?xml version="1.0" encoding="UTF-8"?> <web- ...
- 使用Servlet3.0新特性asyncSupported=true时抛异常java.lang.IllegalStateException: Not supported
最近在运用Servlet3.0新特性:异步处理功能的时候出现以下了2个问题: 运行时会抛出以下两种异常: 一月 19, 2014 3:07:07 下午 org.apache.catalina.core ...
- Servlet3.0新特性(从注解配置到websocket编程)
Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率.主要新特性有以下几个: 引入注解配置 支持 ...
- Servlet3.0新特性WebFilter(Annotation Filter)详解
摘要: Servlet3.0作为J2EE 6规范一部分,并随J2EE6一起发布,WeFilter是过滤器注解,是Servlet3.0的新特性,不需要在web.xml进行配置,简化了配置. Name T ...
- Java自学手记——servlet3.0新特性
servlet3.0出来已经很久了,但市场上尚未普遍应用,servlet3.0有三个比较重要的新特性:使用注解来代替配置文件,异步处理以及上传组件支持. 支持servlet3.0的要求:MyEclip ...
随机推荐
- 安装第三方包web.py发生的错误
今天新学到了python的模块方面的内容,我的版本是python2.7.13 想安装第三方包web.py的时候, 命令提示符 输入 pip install web.py 总是提示如下错误 You ar ...
- 获取url地址参数值
获取url地址参数值方法: function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + &q ...
- 读书笔记 effective c++ Item 14 对资源管理类的拷贝行为要谨慎
1. 自己实现一个资源管理类 Item 13中介绍了 “资源获取之时也是初始化之时(RAII)”的概念,这个概念被当作资源管理类的“脊柱“,也描述了auto_ptr和tr1::shared_ptr是如 ...
- HTTP状态码理解
100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息. 400-499 用于指出客户端的错 ...
- C# 6 与 .NET Core 1.0 高级编程 - 40 ASP.NET Core(下)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 40 章 ASP.NET Core(下)),不对的地方欢迎指出与交流. 章节出自<Professiona ...
- PHP基础学习(函数一)
PHP(Hypertext Preprocessor):超文本预处理器,一种嵌入在HTML中并且运行在服务器端的脚本语言. var_dump--打印变量相关信息 说明: <?php var_d ...
- 漂亮的代码2:遍历文件夹目录,使用promise
看到一个问题: 找到文件夹下所有文件: 自己写了一个: function walk(dir, ext, callback) { ext = ext.charAt(0) === "." ...
- 将Error异常日志从普通日志中剥离
开发过程中经常需要调试和线上环境查看异常日志的需求,但普通消息与异常消息混在一起实在是非常难得找,上则NM的文档够你头痛,所以就将Error级别的日志抽离出来. 本示例采用log4net来配置: 1. ...
- sql decimal & float & celling 介绍
decimal 可以用在指定几个位数比如 123.456, decimal(3,3), 用这类型计算比较准确. 默认情况下,将数字转换为较低精度和小数位数的 decimal 或 numeric 值时, ...
- 一个简单的php站点配置
一个简单的php站点配置 现在我们来看在一个典型的,简单的PHP站点中,nginx怎样为一个请求选择location来处理: server { listen 80; ...