- 可插拔的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風格,能夠要求響應保持打開,以容許當異步事件產生時發送額外的數據。
- 阻塞/非阻塞通知——通知阻塞或非阻塞事件。
- 頻道概念——訂閱一個頻道,以及從該頻道獲取異步事件的能力。這意味着能夠建立、訂閱、退訂,以及應用一些諸如誰能加入、誰不能加入的安全限制。
- 安全
- 結合
- 其它
- 支持更好的歡迎文件(welcome file)。
- ServletContextListener排序。
- 容器範圍內定義init參數。
- 文件上載——過程偵聽——存儲中間或最終文件。
- 澄清線程安全問題。
咱們下面就看看其中幾個特性:html
1.可插拔的Web框架,其實就是web.xml中能夠又多個子模塊的配置文件組成,而各個子模塊的配置文件能夠放在各個jar包的META-INFO中,這樣就實現web應用的模塊化。java
相似,能夠按照配置的順序指定了web片斷的順序。經過absolute-ordering進行絕對順序配置,經過每一個fragment的order的after和before標籤進行相對順序配置。web
- <?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:
- http:
- <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中定義。安全
@WebFiltercookie
- 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的提示查到對應的參數配置,併發
![](http://static.javashuo.com/static/loading.gif)
@WebServlet支持的參數有app
![](http://static.javashuo.com/static/loading.gif)
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) {
-
- e.printStackTrace();
- } catch (IOException e) {
-
- e.printStackTrace();
- }
- }
- });
- async.addListener(new AsyncListener() {
-
- @Override
- public void onTimeout(AsyncEvent arg0) throws IOException {
-
-
- }
-
- @Override
- public void onStartAsync(AsyncEvent arg0) throws IOException {
-
-
- }
-
- @Override
- public void onError(AsyncEvent arg0) throws IOException {
-
-
- }
-
- @Override
- public void onComplete(AsyncEvent arg0) throws IOException {
-
-
- }
- });
- 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)