Servlet3.0新特性

1 Servlet3.0新特性概述

  使用要求:MyEclipse10.0或以上版本,发布到Tomcat7.0或以上版本,创建JavaEE6.0应用!
  Servlete3.0的主要新特性如下三部分:
    使用@WebServlet、@WebFilter、@WebListener三个注解来替代web.xml文件中的Servlet、Filter、Listener的配置;
    Servlet异步处理:当Servlet处理比较费时的问题时,这会让客户感觉到很卡(原来(Servlete2.5),在服务器没有结束响应之前,浏览器是看不到响应内容的,只有响应结束时,浏览器才能显示结果!)。当使用异常处理时可以把已经处理好的内容先一步响应给客户端浏览器,然后使用另一个线程来完成费时的操作,也就是把内容一部分一部分的显示出来;
    上传组件:不用再使用commons-fileupload等第三方的上传组件,使用Servlet3.0的上传组件会更方便。

2 @WebServlet、@WebFilter、@WebListener(使用前提:删除web.xml文件,好处:配置信息少,缺点:不方便修改) 

@WebServlet( urlPatterns="/AServlet", 
          initParams={    //初始化参数
              @WebInitParam(name="p1", value="v1"),
              @WebInitParam(name="p2", value="v2")
          },
          //标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法),值代表优先级,正数的值越小,优先级越高,启动时就越先加载
          loadOnStartup=1    
)
public class AServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.getWriter().print("hello servlet3.0!!");
    }
}


@WebFilter(urlPatterns="/*")
public class AFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse repsonse,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器。。。。。。。。。。。。");
        chain.doFilter(request, repsonse);
    }
    @Override
    public void destroy() {}
    @Override
    public void init(FilterConfig arg0) throws ServletException {}
}


@WebListener
public class AListener implements ServletContextListener {
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("死掉了");
    }
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("出生了");
    }
}


3 Servlet异步处理
  Servlet异步处理就是让Servlet在处理费时的请求时不要阻塞,而是一部分一部分的显示。也就是说,在使用Servlet异步处理之后,页面可以一部分一部分的显示数据,而不是一直卡,等到请求响应结束后一起显示。
  在使用异步处理之前,一定要在@WebServlet注解中给出asyncSupported=true,不然默认Servlet是不支持异步处理的。如果存在过滤器,也要设置@WebFilter的asyncSupportedt=true。注意,响应类型必须是text/html,所以要设置:response.setContentType(“text/html;charset=utf-8”);

  使用异步处理大致可以分为两步:Servlet正常响应数据,Servlet异常响应数据。

  在Servlet正常响应数据时,没什么可说的,可通知response.getWriter().print()来向客户端输出,但输出后要使用response.getWriter().flush()刷新,不然数据只是在缓冲区中,不能向客户端发送数据的。
  异步响应数据需要使用request.startAsync()方法获取AsyncContext对象。然后调用AsyncContext对象的start()方法启动异步响应,start()方法需要一个Runnable类型的参数。在Runnable的run()方法中给出异步响应的代码。注意在异步处理线程中使用response做响应后,要使用response.getWriter().flush()来刷新流,不然数据是不能响应到客户端浏览器的。
@WebServlet(urlPatterns="/AServlet", asyncSupported=true)
public class AServlet extends HttpServlet {
    public void doGet(final HttpServletRequest req, final HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //兼容IE!如果输出不足512B,IE没有异步效果!
        for(int i = 0; i <= 512; i++) {
            resp.getWriter().print("a");
        }
        resp.getWriter().flush();
        //得到异步上下文对象
        final AsyncContext ac = req.startAsync(req, resp);
        /**
         * 设置超时时间为10秒,Tomcat需要知道异步响应是否结束,如果响应不结束,虽然客户端浏览器会看到响应的数据,但是鼠标上只是有个圈圈的不行的转啊转的,表示还没有结束响应。Tomcat会等待到超时为止,这个超时的时间可以通过AsyncContext类的getTimeout()方法获取,Tomcat默认为20000毫秒。当然也可以通过此方法方法设置
         */
        ac.setTimeout(1000*10);
        //给上下文对象一个Runnable对象,让它执行这个任务
        ac.start(new Runnable() {
            public void run() {
                println("现在马上开始<br/>", resp);
                sleep(2000);
                for(char c = 'A'; c <= 'Z'; c++) {
                    println(c+"", resp);
                    sleep(250);
                }
                ac.complete();// 通知Tomcat我们已经执行结束了!
            }
        });
    }
    public void println(String text, HttpServletResponse resp) {
        try {
            resp.getWriter().print(text);
            resp.getWriter().flush();
        } catch (IOException e) {
        }
    }
    public void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
        }
    }
}


4 文件上传
  Servlet3.0提供了文件上传的处理方案。只需要在Servlet上添加@MultipartConfig注解即可。

  当然也可以为@MultipartConfig注解指定属性值,它有四个属性:
    int filesizeThreshold:指定缓存的大小,当超出这个大小后,文件会保存到磁盘上;
    String location:指定临时文件的目录;
    long maxFilesize:指定上传单个文件的大小限制,如果上传的谁的超出了这个大小,那么就会抛出异常;
    long maxRequestSize:指定整个表单的大小限制。

  当在Servlet上使用了@MultipartConfig注解后,那么就可以使用request.getPart(“fieldName”)来获取<input:file>的内容,其中Part表示一个文件表单项。
<form action="<c:url value='/AServlet'/>" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username"/><br/>
    简 历:<input type="file" name="resume"/><br/>
        <input type="submit" value="注册"/>
</form>

@WebServlet(urlPatterns="/AServlet")
@MultipartConfig(maxFileSize=1024*1024)
public class AServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //getParameter()方法可以使用了!!!
        String username = req.getParameter("username");//可以使用了!!!
        //获取文件表单字段,对应的Part对象
        Part part = req.getPart("resume");
        //从Part中获取需要的数据
        System.out.println(part.getContentType());//获取上传文件的MIME类型
        System.out.println(part.getSize());// 获取上传文件的字节数
        System.out.println(part.getName());// 获取文件字段名称
        System.out.println(part.getHeader("Content-Disposition"));// 获取头,这个头中包含了上传文件的名称
        part.write("C:/xxx.jpg");// 保存上传文件
        // 截取上传文件名称
        String filename = part.getHeader("Content-Disposition");
        int start = filename.lastIndexOf("filename=\"") + 10;
        int end = filename.length() - 1;
        filename = filename.substring(start, end);
        System.out.println(filename);
    }
}

猜你喜欢

转载自javakill.iteye.com/blog/2381670