首页 > 代码库 > Servlet3.0新特性

Servlet3.0新特性

 

时间:2017-1-4 16:51

 

——Servlet3.0新特性概述


前提:
    1、MyEclipse1.0或以上版本
    2、发布到Tomcat7.0或以上版本

步骤:
    1、创建JavaEE6.0项目
        在web.xml文件中有如下字样,即JavaEE6.0项目(是否Servlet3.0)

            <web-app version="3.0">


新特性:
    1、使用@WbServlet、@WebFilter、@WebListener三个注解来替代web.xml文件中的Servlet、Filter、Listener的配置。

    2、Servlet异步处理:
        当Servlet处理比较费时的问题时,会让客户感觉到很卡,当使用异步处理时可以把已经处理好的内容先一步响应给客户端浏览器,然后使用另一个线程来完成费时的操作,也就是把内容一部分一部分显示出来。

    3、上传组件:不再使用fileupload等第三方的上传组件,使用Servlet3.0的上传组件会更方便。


——注解替代配置文件


配置Servlet:

    1、删除web.xml文件
    2、创建class文件,而不是Servlet文件
    3、在Servlet类上添加:@WebServlet(urlPatterns="/AServlet")

    总结:
        注解优点:配置信息少
        注解缺点:不方便修改,如果需要修改注解,则需要修改源码

示例代码:

    @WebServlet(urlPatterns="/AServlet",
        initParams={
            @WebInitParam(name="p1", value="http://www.mamicode.com/v1"),
            @WebInitParam(name="p2", value="http://www.mamicode.com/v2")},
        loadOnStartup=1
    )




配置Filter:

    @WebFilter(urlPatterns = "/*")
    public class AFilter implements Filter { }

配置Listener:

    @WebListener
    public class AListener implements ServletContextListener { 



——异步处理

1、什么是异步处理
    原来在服务器没有结束响应之前,浏览器是看不到相应内容的,只有响应结束时,浏览器才能显示结果。
    现在异步处理的作用,在服务器开始响应后,浏览器就可以看到相应内容了,不需要等待服务器响应结束。

2、实现异步的步骤
    1)得到AsyncContext,它是异步上下文对象
        AsyncContext ac = request.startAsync(request, response);

    2)给上下文一个Runnable对象,并启动。(给上下文一个任务,让它完成)
        ac.start(new Runnable(){
            public void run(){

            }
        });

3、需要注意
    *   @WebServlet(urlPatterns="/AServlet", asyncSupported=true)
        必须设置支持异步
    *   response.setContentType("text/html;charset=utf-8");
        必须设置响应体类型
    *   IE默认响应体小于512b,不执行显示输出
    *   ac.complete()
        通知Tomcat异步线程已经结束了,Tomcat会即时断开链接,否则Tomcat会以响应超时结束线程。


示例代码:

import javax.servlet.AsyncContext;
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;
 
/*
 * 
 */
@WebServlet(urlPatterns = "/AServlet", asyncSupported = true)
public class AServlet extends HttpServlet {
    // 内部类中使用外部、局部变量,必须为final
    public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        /*
         * 1、得到异步上下文对象
         */
        final AsyncContext ac = request.startAsync(request, response);
        /*
         * 2、给上下文对象一个Runnable对象,让它执行这个任务
         */
        ac.start(new Runnable() {
            public void run() {
                println("现在开始<br/>", response);
                sleep(2 * 1000);
                for (char c = ‘A‘; c <= ‘Z‘; c++) {
                    println(c + "", response);
                    sleep(100);
                }
                /*
                 * 通知Tomcat该线程已经结束,否则服务器会等待超时,自动结束
                 */
                ac.complete();
            }
        });
    }
 
    public void println(String text, HttpServletResponse response) {
        try {
            response.getWriter().println(text);
            // 如果流没有正常关闭,会抛出异常 
            response.getWriter().flush();
        } catch (Exception e) {
        }
    }
 
    public void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
        }
    }
}



——上传支持

1、上传对表单的要求:
    *   method="post"
    *   enctype="multipart/form-data",默认值:application/x-www-form-urlencoded
    *   <input type="file" name=" " />

2、上传对Servlet的使用
    *   request.getParameter()
        已过时。
    *   request.getInputStream()
        使用它来获取整个表单的数据。

3、commons-fileupload
    >   创建工厂
    >   解析器
    >   使用解析器来解析request,得到List<FileItem>


——Servlet3.0对上传提供支持

*   表单不变
*   在Servlet中不需要再使用commons-fileupload,而是使用Servlet3.0提供的上传组件接口。

上传的步骤:
    1、使用request.getPart("字段名"),得到Part实例。
    2、Part:
        >   String  getConetntType()
            获取上传文件的MIME类型
        >   String  getName()
            获取表单项的名称,不是文件名称
        >   String  getHeader(String header)
            获取指定头的值
        >   long  getSize()
            获取上传文件的大小
        >   InputStream  getInputStream()
            获取上传文件的内容
        >   void  write(String fileName)
            把上传文件保存到指定路径下

    默认Servlet是不支持使用上传组件,需要给Servlet添加一个注解:
        @MultipartConfig


    它没有提供获取上传文件名的方法:
        这需要我们自己从Content-Disposition头中截取。

package com.wyc.web.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(urlPatterns="/BServlet")
@MultipartConfig
public class BServlet extends HttpServlet{
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
        request.setCharacterEncoding("utf-8");
        /*
         * 1、使用getParameter()方法获取表单参数
         */
        String username = request.getParameter("username");
        /*
         * 2、获取文件表单字段,对应Part对象
         */
        Part part = request.getPart("resume");
        /*
         * 3、从Part中获取需要的数据
         *   *  获取上传文件的MIME类型
         *   *  获取上传文件的字节数
         *   *  获取上传文件字段名称(name)
         *   *  获取上传文件的名称
         */
        String mime = part.getContentType();
        System.out.println(mime);
 
        long size = part.getSize();
        System.out.println(size);
 
        String name = part.getName();
        System.out.println(name);
 
        String head = part.getHeader("Content-Disposition");
        System.out.println(head);

        /*
         * 手动截取文件名
         */
        String fileName = head.substring(head.indexOf("filename") + 10, head.length() - 1);
        System.out.println(fileName);
        /*
         * 4、保存上传文件
         */
        part.write("F:/aa.mp3");
    }
}

Servlet3.0新特性