Servlet3.0新特性使用詳解

  • 可插拔的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風格,能夠要求響應保持打開,以容許當異步事件產生時發送額外的數據。
    • 阻塞/非阻塞通知——通知阻塞或非阻塞事件。
    • 頻道概念——訂閱一個頻道,以及從該頻道獲取異步事件的能力。這意味着能夠建立、訂閱、退訂,以及應用一些諸如誰能加入、誰不能加入的安全限制。
  • 安全
    • login/logout能力。
    • 自注冊。
  • 結合
    • 結合/需求,來自REST JST JSR(JSR 311 )。
    • 結合/需求,來自JSF 2.0 JSR(JSR 134 )。
  • 其它
    • 支持更好的歡迎文件(welcome file)。
    • ServletContextListener排序。
    • 容器範圍內定義init參數。
    • 文件上載——過程偵聽——存儲中間或最終文件。
    • 澄清線程安全問題。

 

 

咱們下面就看看其中幾個特性:html

1.可插拔的Web框架,其實就是web.xml中能夠又多個子模塊的配置文件組成,而各個子模塊的配置文件能夠放在各個jar包的META-INFO中,這樣就實現web應用的模塊化。java

 相似,能夠按照配置的順序指定了web片斷的順序。經過absolute-ordering進行絕對順序配置,經過每一個fragment的order的after和before標籤進行相對順序配置。web

 

[java]  view plain copy
 
  1. <?xml version="1.0" encoding="GB18030"?>  
  2. <web-app version="3.0"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  
  7.     <absolute-ordering>  
  8.         <name>web-fragment1</name>  
  9.         <name>web-fragment2</name>  
  10.     </absolute-ordering></web-app>  



 

每一個fragment1的配置以下:數據庫

 

[html]  view plain copy
 
  1. <?xml version="1.0" encoding="GB18030"?>  
  2. <web-fragment version="3.0"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">  
  7.   
  8.     <name>web-fragment1</name>  
  9.     <ordering><after>web-fragment1</after><before><others/></before></ordering>  
  10.   
  11. </web-fragment>  

 

 

2. servlet3.0的annotation支持編程

對於原來在web.xml定義的servlet,filter,listener,InitParam均可以經過annotation來配置了,而不須要在web.xml中定義。安全

@WebFiltercookie

 

[html]  view plain copy
 
  1. import java.io.IOException;  
  2.   
  3. import javax.servlet.Filter;  
  4. import javax.servlet.FilterChain;  
  5. import javax.servlet.FilterConfig;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletRequest;  
  8. import javax.servlet.ServletResponse;  
  9. import javax.servlet.annotation.WebFilter;  
  10. import javax.servlet.annotation.WebInitParam;  
  11.   
  12. //asyncSupported=true 對應filter也須要定義asyncSupported=true  
  13. @WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)  
  14. @WebInitParam(name="a", value="valuea")  
  15. public class My3Filter implements Filter{  
  16.   
  17.     @Override  
  18.     public void destroy() {  
  19.         // TODO Auto-generated method stub  
  20.           
  21.     }  
  22.   
  23.     @Override  
  24.     public void doFilter(ServletRequest arg0, ServletResponse arg1,  
  25.             FilterChain arg2) throws IOException, ServletException {  
  26.         System.out.println("servlet 3 filter");  
  27.         arg2.doFilter(arg0, arg1);  
  28.     }  
  29.   
  30.     @Override  
  31.     public void init(FilterConfig arg0) throws ServletException {  
  32.         System.out.println("servlet 3 filter init");  
  33.     }  
  34.   
  35. }  


@WebServlet網絡

 

 

[html]  view plain copy
 
  1. import java.io.IOException;  
  2.   
  3. import javax.servlet.Filter;  
  4. import javax.servlet.FilterChain;  
  5. import javax.servlet.FilterConfig;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletRequest;  
  8. import javax.servlet.ServletResponse;  
  9. import javax.servlet.annotation.WebFilter;  
  10. import javax.servlet.annotation.WebInitParam;  
  11.   
  12. //asyncSupported=true 對應filter也須要定義asyncSupported=true  
  13. @WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)  
  14. @WebInitParam(name="a", value="valuea")  
  15. public class My3Filter implements Filter{  
  16.   
  17.     @Override  
  18.     public void destroy() {  
  19.         // TODO Auto-generated method stub  
  20.           
  21.     }  
  22.   
  23.     @Override  
  24.     public void doFilter(ServletRequest arg0, ServletResponse arg1,  
  25.             FilterChain arg2) throws IOException, ServletException {  
  26.         System.out.println("servlet 3 filter");  
  27.         arg2.doFilter(arg0, arg1);  
  28.     }  
  29.   
  30.     @Override  
  31.     public void init(FilterConfig arg0) throws ServletException {  
  32.         System.out.println("servlet 3 filter init");  
  33.     }  
  34.   
  35. }  

 

 

支持的annotation以下,均可以經過eclipse的提示查到對應的參數配置,併發


@WebServlet支持的參數有app


 

 

 

3. servlet3.0的異步支持

不少時候Servlet要和其餘的資源進行互動,例如訪問數據庫,調用web service。在和這些資源互動的時候,Servlet不得不等待數據返回,而後纔可以繼續執行。這使得Servlet調用這些資源的時候阻塞。Servlet3.0經過引入異步處理解決了這個問題。異步處理容許線程調用資源的時候不被阻塞,而是直接返回。AsyncContext負責管理從資源來的迴應。AsyncContext決定該回應是應該被原來的線程處理仍是應該分發給容器中其餘的資源。AsyncContext有一些方法如start,dispatch和complete來執行異步處理。 
要想使用Servlet3.0的異步處理,咱們須要設置@Webservlet和@WebFilter註解的asyncSupport屬性。這個屬性是布爾值,缺省值是false。

因此,能夠在servlet阻塞處理網絡,數據庫查詢等時,能夠暫時釋放線程資源,處理更多請求,當請求處理完以後從新喚醒線程繼續處理原來的請求,達到NIO的效果。

咱們看下一個示例

[java]  view plain copy
 
  1. AsyncContext 能夠添加監聽器做爲異步處理過程當中狀態的跟蹤等  

 

 

[java]  view plain copy
 
  1. import java.io.IOException;  
  2. import java.util.Date;  
  3.   
  4. import javax.servlet.AsyncContext;  
  5. import javax.servlet.AsyncEvent;  
  6. import javax.servlet.AsyncListener;  
  7. import javax.servlet.ServletConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.annotation.WebServlet;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. @WebServlet(asyncSupported=true,name="asyncServlet", urlPatterns="/async")  
  16. public class AsyncServlet extends HttpServlet{  
  17.   
  18.     /** 
  19.      *  
  20.      */  
  21.     private static final long serialVersionUID = 3903580630389463919L;  
  22.   
  23.     @Override  
  24.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  25.             throws ServletException, IOException {  
  26.         resp.getWriter().write("hello, async test");  
  27.         resp.getWriter().println("start:"+new Date()+".<br/>");   
  28.         resp.getWriter().flush();  
  29.         final AsyncContext async = req.startAsync(req,resp);  
  30.         async.setTimeout(3000);  
  31.         async.start(new Runnable() {  
  32.             @Override  
  33.             public void run() {  
  34.                 ServletRequest request = async.getRequest();  
  35.                 try {  
  36.                     Thread.sleep(2000);  
  37.                     async.getResponse().getWriter().write("aync thread processing");  
  38.                     async.getResponse().getWriter().flush();  
  39.                     async.getResponse().getWriter().println("async end:"+new Date()+".<br/>");   
  40.                     async.getResponse().getWriter().flush();  
  41.                 } catch (InterruptedException e) {  
  42.                     // TODO Auto-generated catch block  
  43.                     e.printStackTrace();  
  44.                 } catch (IOException e) {  
  45.                     // TODO Auto-generated catch block  
  46.                     e.printStackTrace();  
  47.                 }  
  48.             }  
  49.         });  
  50.         async.addListener(new AsyncListener() {  
  51.               
  52.             @Override  
  53.             public void onTimeout(AsyncEvent arg0) throws IOException {  
  54.                 // TODO Auto-generated method stub  
  55.                   
  56.             }  
  57.               
  58.             @Override  
  59.             public void onStartAsync(AsyncEvent arg0) throws IOException {  
  60.                 // TODO Auto-generated method stub  
  61.                   
  62.             }  
  63.               
  64.             @Override  
  65.             public void onError(AsyncEvent arg0) throws IOException {  
  66.                 // TODO Auto-generated method stub  
  67.                   
  68.             }  
  69.               
  70.             @Override  
  71.             public void onComplete(AsyncEvent arg0) throws IOException {  
  72.                 // TODO Auto-generated method stub  
  73.                   
  74.             }  
  75.         });  
  76.         resp.getWriter().println("end:"+new Date()+".<br/>");   
  77.         resp.getWriter().flush();  
  78.            
  79.     }  
  80.   
  81. }  


輸出以下: 這裏先對線程後面的println先輸出,最後在處理輸出異步線程輸出的內容。

 

 

[html]  view plain copy
 
  1. hello, async teststart?Mon Dec 10 20:23:35 CST 2012.  
  2. end?Mon Dec 10 20:23:35 CST 2012.  
  3. 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參數指定臨時文件存放目錄,'

 

 

[java]  view plain copy
 
  1. package com.servlet;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.annotation.MultipartConfig;  
  7. import javax.servlet.annotation.WebServlet;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11. import javax.servlet.http.Part;  
  12.   
  13.   
  14. @WebServlet(asyncSupported=true,name="upload", urlPatterns="/upload")  
  15. @MultipartConfig(fileSizeThreshold = 10000, maxFileSize = 1000000, maxRequestSize = 1000000, location="E:/logs")  
  16. public class MultiPartServlet3 extends HttpServlet {  
  17.   
  18.     /** 
  19.      *  
  20.      */  
  21.     private static final long serialVersionUID = 7306582588845300635L;  
  22.   
  23.     @Override  
  24.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  25.             throws ServletException, IOException {  
  26.         Part part = req.getPart("file");  
  27.         String value = part.getHeader("content-disposition");  
  28.         System.out.println(value);  
  29.         String filename = value.substring(value.lastIndexOf("=") + 2,value.length() - 1);  
  30.         System.out.println(filename);  
  31.         System.out.println(part.getInputStream().toString());  
  32.     }  
  33.   
  34. }  



 

 咱們寫一個文件上傳的頁面

 

 

[html]  view plain copy
 
  1. <form action="upload" method="post" enctype="multipart/form-data">  
  2.     <input type="file" name="file"><br<input type="submit"  
  3.         value="submit">  
  4. </form>  


隨便上傳一個文件,我這邊的輸出爲:

 

 

[html]  view plain copy
 
  1. form-data; name="file"; filename="22.log"  
  2. 22.log  
  3. java.io.ByteArrayInputStream@1bdce67  


5.已有API改進,特別是支持動態加載servlet,熱部署功能

 

 

[java]  view plain copy
 
    1. HttpServletRequest   
    2. To support the multipart/form-data MIME type, the following methods have been added to the HttpServletRequest interface:   
    3. 爲了支持multipart/form-data MIME類型,在HttpServletRequest接口中添加了項目的方法:   
    4.     * Iterable<Part> getParts()   
    5.     * Part getPart(String name)   
    6. Cookies   
    7. 爲了不一些跨站點攻擊,Servlet3.0支持HttpOnly的cookie。HttpOnly cookie不想客戶端暴露script代碼。Servlet3.0在Cookie類中添加了以下的方法來支持HttpOnly cookie:   
    8.     * void setHttpOnly(boolean isHttpOnly)   
    9.     * boolean isHttpOnly()   
    10. ServletContext   
    11. 經過在ServletContext中添加下面的方法,Servlet3.0容許Servlet或filter被編程的加入到context中:   
    12.     * addServlet(String servletName, String className)   
    13.     * addServlet(String servletName, Servlet servlet)   
    14.     * addServlet(String servletName, Class<? extends Servlet> servletClass)   
    15.     * addFilter(String filterName, String className)   
    16.     * addFilter(String filterName, Filter filter)   
    17.     * addFilter(String filterName, Class<? extends Filter>filterClass)   
    18.     * setInitParameter (String name, String Value)  
相關文章
相關標籤/搜索