歡迎您光臨本站 註冊首頁

Java EE 6 Web層:Servlet獲得非同步支持

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  很多Java Web應用都是基於某個框架的,如Apache Wicket、Java ServerFaces、Struts或是Spring MVC等等.要想使用框架,開發者需要在應用的web.xml配置文件中註冊框架的切入代碼,如Servlet、Filter或是Listener.這麼做的後果就是部署描述符變得很龐大,同時導致框架所用的XML與特定於應用的XML混雜在了一起.Servlet 3.0規範的一個主要目標就是讓開發者無需編輯web.xml部署描述符就能部署Servlet、Filter和Listener,同時可以將web.xml文件拆分成多個模塊.為了實現這一點,Servlet 3.0規範增加了基於註解的配置(@WebServlet、@ServletFilter以及@WebServletContextListener),這是的我們可以不再需要web.xml文件,同時規範還引入了一個新的概念:Web片段(Web Fragment).

  Web片段可以將框架的「樣板」XML與應用的其他配置分開,並且能夠實現應用的自我註冊.Web片段必須放在名為web-fragment.xml的文件中,該文件只要位於Web應用的classpath下即可,但通常都將其放到META-INF目錄下或是框架的jar文件中.XML以<web-fragment>元素開始,裡面包含的元素與web.xml部署描述符大同小異.如下代碼所示:

  <web-fragment>

  <filter>

  <filter-name>MyXSSFilter</filter-name>

  <filter-class> MyXssFilter</filter-class>

  </filter>

  <servlet>

  <servlet-name>myFrameworkServlet</servlet-name>

  <servlet-class> MyFrameworkServlet</servlet-class>

  </servlet>

  <listener>

  <listener-class> MyFrameworkListener</listener-class>

  </listener>

  </web-fragment>

  容器在部署時會處理XML片段並組裝成最終的部署描述符.由於容器負責組裝web.xml文件,因此如果需要按照特定的順序來調用框架的Servlet、Listener或Filter時就可能產生問題.為了避免這個問題,Servlet 3.0 API支持絕對與相對順序的部署描述符.我們可以在web.xml文件中使用<absolute-ordering>元素指定絕對順序,這樣WEB-INF/lib下的每個jar都可以通過META-INF/web-fragment.xml文件的<name>元素獲得一個名字.接下來,Web應用的WEB-INF/web.xml文件可以通過<absolute-ordering>元素按照順序列舉出這些片段名,這個順序就是jar的調用順序,同時還有一個可選的<others/>元素用於指定是否以及何時包含那些未命名的jar文件.由於部署者可以選擇只列出那些受信任的jar以進行部署,這樣就可以避免意外情況的發生.除此之外,通過順序還可以排除那些不需要被掃描的jar,這樣就可以加快應用的部署速度.,如果你不想在產品環境下看到自我註冊的情況發生,那就可以在web.xml文件中使用<metadata-complete>元素,這會告訴Web容器只去尋找註解而非Web片段.

  由於既支持片段,又可以使用註解作為另一種配置機制,Servlet 3.0可以插入框架的共享拷貝,比如JAX-WS、JAX-RS以及JSF等,他們都構建在Web容器之上,使用了ServletContainerInitializers.這些框架是通過jar services API被檢測到的,同時還可以指定其處理的類型列表.對於WEB-INF/lib下的任何jar來說,只要其中包含的類被檢測到都會傳遞給ServletContainerInitializer.這樣,我們還可以將同樣的API作為ServletContextListeners.

  從Servlet API首次發布以來,構建Web應用的方法發生了翻天覆地的變化,尤其是使用越來越多的非同步Web技術.這些技術(一般統稱為Ajax或是Web 2.0)對於Web客戶端(比如瀏覽器)與伺服器端之間的傳輸機制產生了重要的影響,客戶端會在一個頁面中向伺服器端發出更多的請求而不是每次請求都刷新一次頁面.

  長時間的伺服器端處理會惡化這一情況,比如等待JDBC連接池中的連接,或是等待JMS隊列中的消息等.在Servlet中等待實在是太低效了,這種阻塞會消耗線程以及其他有限的系統資源.鑒於此,Servlet 3.0引入了非同步處理請求的功能,這樣線程就可以返回到容器中並執行其他任務.在請求上的非同步處理開始時,其他線程或是回調既可以生成響應,也可以分發請求以便通過AsyncContext.dispatch方法在容器上下文中執行請求.

  由於非同步Servlet的行為與同步的差別非常大,因此Servlet 3.0要求開發者指定asyncSupported=true以表示Servlet支持非同步請求.不僅是Servlet,Filter也可以非同步執行.Servlet 3.0通過新的ServletRequest方法來支持非同步處理,比如startAsync()會返回一個AsyncContext對象,該對象用於持有傳遞給方法的request與response對象.這裡,處理原始請求的線程還可以執行其他操作.此外,API還引入了一個新的Listener類:AsyncListener,它會告訴我們非同步操作何時結束或者是否超時了.AsyncContext類擁有一個complete()方法,憑藉該方法我們可以在非同步操作結束后提交響應.AsyncListener類擁有一個dispatch()方法,它會將非同步請求轉發給容器,這樣其他框架(比如JSP)就可以生成響應了.

  除了引入大量的新技術和新方法外,Servlet 3.0規範還對其他地方進行了大量的增強:HttpServletRequest終於獲得對multipart/form-data MIME類型的內置支持了、Cookie類開始支持「HttpOnly」 cookie以避免某些跨站點的腳本攻擊、ServletContext API也得到了更新,我們可以通過編程的方式將Servlet和Filter加到上下文中了.


[火星人 ] Java EE 6 Web層:Servlet獲得非同步支持已經有882次圍觀

http://coctec.com/docs/java/show-post-60616.html