初次接触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!!"); } }
总结:
注解的优缺点:配置信息少,不方便修改
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 { } }
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("出生了!"); } }
五、异步处理
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) { } } }
----------------------------------------
六、上传支持
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>
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); } }