初次接触Servlet3.0

Servlet3.0

一、要求
MyEclipes10.0或以上版本!
发布到Tomcat7.0或以上版本!
二、步骤
创建JavaEE6.0应用

-------------------------------------------
三、概述
*注解代替web.xml配置文件
*异步处理
*对上传的支持

Servlet3.0在市场上没有应用!

--------------------------------------------
四、注解替代配置文件
1、删除web.xml
2、在servlet类上添加@WebServlet(urlPatterns={"/AServlet"})

package cn.itcast.web.servlet;

import java.io.IOException;

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>AServlet</servlet-name>
     <servlet-class>cn.itcast.web.servlet.AServlet</servlet-class>
     <init-param>
         <param-name>p1</param-name>
         <param-value>v1</param-value>
     </init-param>
     <init-param>
         <param-name>p2</param-name>
         <param-value>v2</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
     <servlet-name>AServlet</servlet-name>
     <url-pattern>/AServlet</url-pattern>
     <url-pattern>/AAServlet</url-pattern>
 </servlet-mapping>
 */
@WebServlet(urlPatterns="/AServlet",
        initParams={ //这个既然修改不了,为什么不直接在servlet对应地方书写呢,所以无太大意义,一般不适用
            @WebInitParam(name="p1",value="v1"),
            @WebInitParam(name="p2",value="v2"),
        },
        loadOnStartup=1    
)
public class AServlet extends HttpServlet{
    
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("hello servlet3.0!");
        resp.getWriter().print("hello 3.0!!");
    }
}
View Code

总结:
注解的优缺点:配置信息少,不方便修改
3、在Filter类上面添加@WebFilter(urlPattern="/AFilter")

package cn.itcast.web.filter;

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;

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

    @Override
    public void destroy() {
        
    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        System.out.println("哈哈,看到我了没有!");
        arg2.doFilter(arg0, arg1);
    }

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

}
View Code

4、在Listener类上添加@WebListener

package cn.itcast.web.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class AListener implements ServletContextListener{

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("死掉了!");
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("出生了!");
    }

}
View Code

五、异步处理
1、什么是异步处理
原来,在服务器没有结束响应之前,客户端浏览器是看不到响应内容的,只有响应结束时候,浏览器才能显示结果!
现在异步处理的而作用:在服务器开始响应后,浏览器就可以看到响应内容,不用等待响应结束

2、实现异步的步骤
*得到AsyncContext,它是异步上下文对象
AsyncContext ac=request.startAsync(request,response);
*给上下文一个Runnable对象,启动它!(给上下文一个任务,让它完成!)
ac.start(new Runnable(){
public void run(){
...
}
});

*@WebServlet(urlPattern="/AServlet",asyncSupported=true)
*resp.setContentType("text/html;charset=utf-8");
*IE如果不能正常输出,这说明响应体大小不足521B,那么你多补充一点废话就可以了
*AstnContext#complete():通知Tomcat我们异步线程已经执行完毕了

package cn.itcast.web.servlet;

import java.io.IOException;

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="/AServlet",asyncSupported=true)
public class AServlet extends HttpServlet{

    /* 不异步
     public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.getWriter().print("hello");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
        resp.getWriter().print("word");
        resp.getWriter().flush();
    }
    */
     public void doGet(HttpServletRequest req, final HttpServletResponse resp)
        throws ServletException, IOException {
         resp.setContentType("text/html;charset=utf-8");
         for(int i=0;i<=512;i++){
             resp.getWriter().print("a");
         }
         /*
          * 得到异步上下文对象
          */
         final AsyncContext ac=req.startAsync(req, resp);
         /*
          * 给上下文对象一个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);
                }
                //通知Tomcat该线程已经结束了
                ac.complete();
            }
         });
     }
     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) {
        }
     }
}
View Code

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

*上传Servlet的使用
request.getParameter()相关不能再使用
request.getInputStream()使用它来获取整个表单的数据

*commons-fileupload
创建工厂
解析器
使用解析器得到List<FileItem>

=====================
Servlet3.0对上传提供了支持:
*表单不变
*在Servlet中不需要再使用commons-fileupload,而是使用Servlet3.0提供的上传接口

=====================
上传的步骤:
*使用request.getPart("字段名"),得到Part实例
*Part:
>String getContentType():获取上传文件的MIME类型
>String getName():获取表单项的名称,不是文件名称
>String getHeader(String header):获取指定头的值
>long getSize():获取上传文件的大小
>InputStream getInputStream():获取上传文件的内容
>void write(String fileName):把上传文件保存到指定路径下
*默认Servlet是不支持使用上传组件:需要给Servlet添加一个注解:@MultipartConfig

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

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'form.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <h1>注册</h1>
    <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>
  </body>
</html>
form.jsp
package cn.itcast.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="/AServlet")
@MultipartConfig
public class AServlet extends HttpServlet{

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        /*
         * getParameter()可以使用了
         */
        String username=req.getParameter("username");
        /*
         * 获取文件表单字段
         */
        Part part=req.getPart("resume");
        /*
         * 从Part中获取需要的数据
         */
        //获取上传文件的MIME类型
        System.out.println(part.getContentType());
        //获取上传文件的字节数
        System.out.println(part.getSize());
        //获取文件字段名称
        System.out.println(part.getName());
        //获取头,这个头包含了上传文件名称
        System.out.println(part.getHeader("Content-Disposition"));
        String filename=part.getHeader("Content-Disposition");
//        filename=filename.split("filename=")[1].split(""")[1];
        int start=filename.lastIndexOf("filename="");
        int end=filename.length()-1;
        filename=filename.substring(start,end);
        System.out.println(filename);
        //保存上传文件
        part.write("C:/"+filename);
        
    }
}
AServlet.java
原文地址:https://www.cnblogs.com/aigeileshei/p/5793556.html