2018-11-07

Version:1.0StartHTML:000000231EndHTML:000105074StartFragment:000007472EndFragment:000105042StartSelection:000007472EndSelection:000105042SourceURL:https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/index.html

IBM?

站點地圖

市場

關閉

IBMIn Marketplace提交

我的 IBM

我的 IBM

IBM Developer

登錄

注冊

站點導航

站點導航

關閉

IBM developerWorks

學習

開發(fā)

社區(qū)

合作

市場

產品

產品

立即免費試用

大數(shù)據(jù)與分析

云計算

認知

認知客戶互動

物聯(lián)網

行業(yè)解決方案

IT 基礎架構

移動

IBM 安全

社交協(xié)作與人才管理

Watson

服務

企業(yè)咨詢服務

技術服務

融資

行業(yè)解決方案

培訓與技能 (US)

行業(yè)

開發(fā)人員

developerWorks

PartnerWorld

云/AI 合作伙伴

支持

工作機會

IBM developerWorks

學習

開發(fā)

社區(qū)

合作

學習

Java technology

內容

概覽

Servlet 3.0 新特性概述

異步處理支持

新增的注解支持

可插性支持

ServletContext 的性能增強

HttpServletRequest 對文件上傳的支持

總結

相關主題

評論

Servlet 3.0 新特性詳解

張 建平

2010 年 4 月 23 日發(fā)布

分享此頁面

WeiboGoogle+用電子郵件發(fā)送本頁面

8

Servlet 3.0 新特性概述

Servlet 3.0 作為 Java EE 6 規(guī)范體系中一員,隨著 Java EE 6 規(guī)范一起發(fā)布梆造。該版本在前一版本(Servlet 2.5)的基礎上提供了若干新特性用于簡化 Web 應用的開發(fā)和部署输虱。其中有幾項特性的引入讓開發(fā)者感到非常興奮塞颁,同時也獲得了 Java 社區(qū)的一片贊譽之聲:

異步處理支持:有了該特性,Servlet 線程不再需要一直阻塞爬橡,直到業(yè)務處理完畢才能再輸出響應玖媚,最后才結束該 Servlet 線程贞间。在接收到請求之后挠唆,Servlet 線程可以將耗時的操作委派給另一個線程來完成处窥,自己在不生成響應的情況下返回至容器。針對業(yè)務處理較耗時的情況玄组,這將大大減少服務器資源的占用滔驾,并且提高并發(fā)處理速度谒麦。

新增的注解支持:該版本新增了若干注解,用于簡化 Servlet嵌灰、過濾器(Filter)和監(jiān)聽器(Listener)的聲明弄匕,這使得 web.xml 部署描述文件從該版本開始不再是必選的了颅悉。

可插性支持:熟悉 Struts2 的開發(fā)者一定會對其通過插件的方式與包括 Spring 在內的各種常用框架的整合特性記憶猶新沽瞭。將相應的插件封裝成 JAR 包并放在類路徑下,Struts2 運行時便能自動加載這些插件∈F浚現(xiàn)在 Servlet 3.0 提供了類似的特性驹溃,開發(fā)者可以通過插件的方式很方便的擴充已有 Web 應用的功能,而不需要修改原有的應用延曙。

下面我們將逐一講解這些新特性豌鹤,通過下面的學習,讀者將能夠明晰了解 Servlet 3.0 的變化枝缔,并能夠順利使用它進行日常的開發(fā)工作布疙。

異步處理支持

Servlet 3.0 之前,一個普通 Servlet 的主要工作流程大致如下:首先愿卸,Servlet 接收到請求之后灵临,可能需要對請求攜帶的數(shù)據(jù)進行一些預處理;接著趴荸,調用業(yè)務接口的某些方法儒溉,以完成業(yè)務處理;最后发钝,根據(jù)處理的結果提交響應顿涣,Servlet 線程結束。其中第二步的業(yè)務處理通常是最耗時的酝豪,這主要體現(xiàn)在數(shù)據(jù)庫操作涛碑,以及其它的跨網絡調用等,在此過程中孵淘,Servlet 線程一直處于阻塞狀態(tài)蒲障,直到業(yè)務方法執(zhí)行完畢。在處理業(yè)務的過程中夺英,Servlet 資源一直被占用而得不到釋放晌涕,對于并發(fā)較大的應用,這有可能造成性能的瓶頸痛悯。對此余黎,在以前通常是采用私有解決方案來提前結束 Servlet 線程,并及時釋放資源载萌。

Servlet 3.0 針對這個問題做了開創(chuàng)性的工作惧财,現(xiàn)在通過使用 Servlet 3.0 的異步處理支持巡扇,之前的 Servlet 處理流程可以調整為如下的過程:首先,Servlet 接收到請求之后垮衷,可能首先需要對請求攜帶的數(shù)據(jù)進行一些預處理厅翔;接著,Servlet 線程將請求轉交給一個異步線程來執(zhí)行業(yè)務處理搀突,線程本身返回至容器刀闷,此時 Servlet 還沒有生成響應數(shù)據(jù),異步線程處理完業(yè)務以后仰迁,可以直接生成響應數(shù)據(jù)(異步線程擁有 ServletRequest 和 ServletResponse 對象的引用)甸昏,或者將請求繼續(xù)轉發(fā)給其它 Servlet。如此一來徐许, Servlet 線程不再是一直處于阻塞狀態(tài)以等待業(yè)務邏輯的處理施蜜,而是啟動異步線程之后可以立即返回。

異步處理特性可以應用于 Servlet 和過濾器兩種組件雌隅,由于異步處理的工作模式和普通工作模式在實現(xiàn)上有著本質的區(qū)別翻默,因此默認情況下,Servlet 和過濾器并沒有開啟異步處理特性恰起,如果希望使用該特性修械,則必須按照如下的方式啟用:

對于使用傳統(tǒng)的部署描述文件 (web.xml) 配置 Servlet 和過濾器的情況,Servlet 3.0 為 和 標簽增加了 子標簽村缸,該標簽的默認取值為 false祠肥,要啟用異步處理支持,則將其設為 true 即可梯皿。以 Servlet 為例仇箱,其配置方式如下所示:1

2

3

4

5

<servlet>

????<servlet-name>DemoServlet</servlet-name>

????<servlet-class>footmark.servlet.Demo Servlet</servlet-class>

????<async-supported>true</async-supported>

</servlet>

對于使用 Servlet 3.0 提供的 @WebServlet 和 @WebFilter 進行 Servlet 或過濾器配置的情況,這兩個注解都提供了 asyncSupported 屬性东羹,默認該屬性的取值為 false剂桥,要啟用異步處理支持,只需將該屬性設置為 true 即可属提。以 @WebFilter 為例权逗,其配置方式如下所示:

1

2

@WebFilter(urlPatterns = "/demo",asyncSupported = true)

public class DemoFilter implements Filter{...}

一個簡單的模擬異步處理的 Servlet 示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

@WebServlet(urlPatterns = "/demo", asyncSupported = true)

public class AsyncDemoServlet extends HttpServlet {

????@Override

????public void doGet(HttpServletRequest req, HttpServletResponse resp)

????throws IOException, ServletException {

????????resp.setContentType("text/html;charset=UTF-8");

????????PrintWriter out = resp.getWriter();

????????out.println("進入Servlet的時間:" + new Date() + ".");

????????out.flush();


????????//在子線程中執(zhí)行業(yè)務調用,并由其負責輸出響應冤议,主線程退出

????????AsyncContext ctx = req.startAsync();

????????new Thread(new Executor(ctx)).start();


????????out.println("結束Servlet的時間:" + new Date() + ".");

????????out.flush();

????}

}


public class Executor implements Runnable {

????private AsyncContext ctx = null;

????public Executor(AsyncContext ctx){

????????this.ctx = ctx;

????}


????public void run(){

????????try {

????????????//等待十秒鐘斟薇,以模擬業(yè)務方法的執(zhí)行

????????????Thread.sleep(10000);

????????????PrintWriter out = ctx.getResponse().getWriter();

????????????out.println("業(yè)務處理完畢的時間:" + new Date() + ".");

????????????out.flush();

????????????ctx.complete();

????????} catch (Exception e) {

????????????e.printStackTrace();

????????}

????}

}

除此之外,Servlet 3.0 還為異步處理提供了一個監(jiān)聽器恕酸,使用 AsyncListener 接口表示堪滨。它可以監(jiān)控如下四種事件:

異步線程開始時,調用 AsyncListener 的 onStartAsync(AsyncEvent event) 方法蕊温;

異步線程出錯時袱箱,調用 AsyncListener 的 onError(AsyncEvent event) 方法遏乔;

異步線程執(zhí)行超時,則調用 AsyncListener 的 onTimeout(AsyncEvent event) 方法发笔;

異步執(zhí)行完畢時盟萨,調用 AsyncListener 的 onComplete(AsyncEvent event) 方法;

要注冊一個 AsyncListener了讨,只需將準備好的 AsyncListener 對象傳遞給 AsyncContext 對象的 addListener() 方法即可捻激,如下所示:

1

2

3

4

5

6

7

AsyncContext ctx = req.startAsync();

ctx.addListener(new AsyncListener() {

????public void onComplete(AsyncEvent asyncEvent) throws IOException {

????????// 做一些清理工作或者其他

????}

????...

});

新增的注解支持

Servlet 3.0 的部署描述文件 web.xml 的頂層標簽 有一個 metadata-complete 屬性,該屬性指定當前的部署描述文件是否是完全的量蕊。如果設置為 true铺罢,則容器在部署時將只依賴部署描述文件艇挨,忽略所有的注解(同時也會跳過 web-fragment.xml 的掃描残炮,亦即禁用可插性支持,具體請看后文關于可插性支持的講解)缩滨;如果不配置該屬性势就,或者將其設置為 false,則表示啟用注解支持(和可插性支持)脉漏。

@WebServlet

@WebServlet 用于將一個類聲明為 Servlet苞冯,該注解將會在部署時被容器處理,容器將根據(jù)具體的屬性配置將相應的類部署為 Servlet侧巨。該注解具有下表給出的一些常用屬性(以下所有屬性均為可選屬性舅锄,但是 vlaue 或者 urlPatterns 通常是必需的,且二者不能共存司忱,如果同時指定皇忿,通常是忽略 value 的取值):

表 1. @WebServlet 主要屬性列表

屬性名類型描述

name String 指定 Servlet 的 name 屬性,等價于 <servlet-name>坦仍。如果沒有顯式指定鳍烁,則該 Servlet 的取值即為類的全限定名。

value String[] 該屬性等價于 urlPatterns 屬性繁扎。兩個屬性不能同時使用幔荒。

urlPatterns String[] 指定一組 Servlet 的 URL 匹配模式。等價于 <url-pattern> 標簽梳玫。

loadOnStartup int 指定 Servlet 的加載順序爹梁,等價于 <load-on-startup> 標簽。

initParams WebInitParam[] 指定一組 Servlet 初始化參數(shù)提澎,等價于 <init-param> 標簽姚垃。

asyncSupported boolean 聲明 Servlet 是否支持異步操作模式,等價于 <async-supported> 標簽虱朵。

description String 該 Servlet 的描述信息莉炉,等價于 <description> 標簽钓账。

displayName String 該 Servlet 的顯示名,通常配合工具使用絮宁,等價于 <display-name> 標簽梆暮。

下面是一個簡單的示例:

1

2

3

4

5

@WebServlet(urlPatterns = {"/simple"}, asyncSupported = true,

loadOnStartup = -1, name = "SimpleServlet", displayName = "ss",

initParams = {@WebInitParam(name = "username", value = "tom")}

)

public class SimpleServlet extends HttpServlet{ … }

如此配置之后,就可以不必在 web.xml 中配置相應的 <servlet> 和 <servlet-mapping> 元素了绍昂,容器會在部署時根據(jù)指定的屬性將該類發(fā)布為 Servlet啦粹。它的等價的 web.xml 配置形式如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<servlet>

????<display-name>ss</display-name>

????<servlet-name>SimpleServlet</servlet-name>

????<servlet-class>footmark.servlet.SimpleServlet</servlet-class>

????<load-on-startup>-1</load-on-startup>

????<async-supported>true</async-supported>

????<init-param>

????????<param-name>username</param-name>

????????<param-value>tom</param-value>

????</init-param>

</servlet>

<servlet-mapping>

????<servlet-name>SimpleServlet</servlet-name>

????<url-pattern>/simple</url-pattern>

</servlet-mapping>

@WebInitParam

該注解通常不單獨使用,而是配合 @WebServlet 或者 @WebFilter 使用窘游。它的作用是為 Servlet 或者過濾器指定初始化參數(shù)唠椭,這等價于 web.xml 中 <servlet> 和 <filter> 的 <init-param> 子標簽。@WebInitParam 具有下表給出的一些常用屬性:

表 2. @WebInitParam 的常用屬性

屬性名類型是否可選描述

name String 否指定參數(shù)的名字忍饰,等價于 <param-name>贪嫂。

value String 否指定參數(shù)的值,等價于 <param-value>艾蓝。

description String 是關于參數(shù)的描述力崇,等價于 <description>。

@WebFilter

@WebFilter 用于將一個類聲明為過濾器赢织,該注解將會在部署時被容器處理亮靴,容器將根據(jù)具體的屬性配置將相應的類部署為過濾器。該注解具有下表給出的一些常用屬性 ( 以下所有屬性均為可選屬性于置,但是 value茧吊、urlPatterns、servletNames 三者必需至少包含一個八毯,且 value 和 urlPatterns 不能共存搓侄,如果同時指定,通常忽略 value 的取值 ):

表 3. @WebFilter 的常用屬性

屬性名類型描述

filterName String 指定過濾器的 name 屬性宪彩,等價于 <filter-name>

value String[] 該屬性等價于 urlPatterns 屬性休讳。但是兩者不應該同時使用。

urlPatterns String[] 指定一組過濾器的 URL 匹配模式尿孔。等價于 <url-pattern> 標簽俊柔。

servletNames String[] 指定過濾器將應用于哪些 Servlet。取值是 @WebServlet 中的 name 屬性的取值活合,或者是 web.xml 中 <servlet-name> 的取值雏婶。

dispatcherTypes DispatcherType 指定過濾器的轉發(fā)模式。具體取值包括:

ASYNC白指、ERROR留晚、FORWARD、INCLUDE告嘲、REQUEST错维。

initParams WebInitParam[] 指定一組過濾器初始化參數(shù)奖地,等價于 <init-param> 標簽。

asyncSupported boolean 聲明過濾器是否支持異步操作模式赋焕,等價于 <async-supported> 標簽参歹。

description String 該過濾器的描述信息,等價于 <description> 標簽隆判。

displayName String 該過濾器的顯示名犬庇,通常配合工具使用,等價于 <display-name> 標簽侨嘀。

下面是一個簡單的示例:

1

2

@WebFilter(servletNames = {"SimpleServlet"},filterName="SimpleFilter")

public class LessThanSixFilter implements Filter{...}

如此配置之后臭挽,就可以不必在 web.xml 中配置相應的 <filter> 和 <filter-mapping> 元素了,容器會在部署時根據(jù)指定的屬性將該類發(fā)布為過濾器咬腕。它等價的 web.xml 中的配置形式為:

1

2

3

4

5

6

7

8

<filter>

????<filter-name>SimpleFilter</filter-name>

????<filter-class>xxx</filter-class>

</filter>

<filter-mapping>

????<filter-name>SimpleFilter</filter-name>

????<servlet-name>SimpleServlet</servlet-name>

</filter-mapping>

@WebListener

該注解用于將類聲明為監(jiān)聽器欢峰,被 @WebListener 標注的類必須實現(xiàn)以下至少一個接口:

ServletContextListener

ServletContextAttributeListener

ServletRequestListener

ServletRequestAttributeListener

HttpSessionListener

HttpSessionAttributeListener

該注解使用非常簡單,其屬性如下:

表 4. @WebListener 的常用屬性

屬性名類型是否可選描述

value String 是該監(jiān)聽器的描述信息郎汪。

一個簡單示例如下:

1

2

@WebListener("This is only a demo listener")

public class SimpleListener implements ServletContextListener{...}

如此赤赊,則不需要在 web.xml 中配置 <listener> 標簽了。它等價的 web.xml 中的配置形式如下:

1

2

3

<listener>

????<listener-class>footmark.servlet.SimpleListener</listener-class>

</listener>

@MultipartConfig

該注解主要是為了輔助 Servlet 3.0 中 HttpServletRequest 提供的對上傳文件的支持煞赢。該注解標注在 Servlet 上面,以表示該 Servlet 希望處理的請求的 MIME 類型是 multipart/form-data哄孤。另外照筑,它還提供了若干屬性用于簡化對上傳文件的處理。具體如下:

表 5. @MultipartConfig 的常用屬性

屬性名類型是否可選描述

fileSizeThreshold int 是當數(shù)據(jù)量大于該值時瘦陈,內容將被寫入文件凝危。

location String 是存放生成的文件地址。

maxFileSize long 是允許上傳的文件最大值晨逝。默認值為 -1蛾默,表示沒有限制。

maxRequestSize long 是針對該 multipart/form-data 請求的最大數(shù)量捉貌,默認值為 -1支鸡,表示沒有限制。

可插性支持

如果說 3.0 版本新增的注解支持是為了簡化 Servlet/ 過濾器 / 監(jiān)聽器的聲明趁窃,從而使得 web.xml 變?yōu)榭蛇x配置牧挣, 那么新增的可插性 (pluggability) 支持則將 Servlet 配置的靈活性提升到了新的高度。熟悉 Struts2 的開發(fā)者都知道醒陆,Struts2 通過插件的形式提供了對包括 Spring 在內的各種開發(fā)框架的支持瀑构,開發(fā)者甚至可以自己為 Struts2 開發(fā)插件,而 Servlet 的可插性支持正是基于這樣的理念而產生的刨摩。使用該特性寺晌,現(xiàn)在我們可以在不修改已有 Web 應用的前提下世吨,只需將按照一定格式打成的 JAR 包放到 WEB-INF/lib 目錄下,即可實現(xiàn)新功能的擴充呻征,不需要額外的配置另假。

Servlet 3.0 引入了稱之為“Web 模塊部署描述符片段”的 web-fragment.xml 部署描述文件,該文件必須存放在 JAR 文件的 META-INF 目錄下怕犁,該部署描述文件可以包含一切可以在 web.xml 中定義的內容边篮。JAR 包通常放在 WEB-INF/lib 目錄下,除此之外奏甫,所有該模塊使用的資源戈轿,包括 class 文件、配置文件等阵子,只需要能夠被容器的類加載器鏈加載的路徑上思杯,比如 classes 目錄等。

現(xiàn)在挠进,為一個 Web 應用增加一個 Servlet 配置有如下三種方式 ( 過濾器色乾、監(jiān)聽器與 Servlet 三者的配置都是等價的,故在此以 Servlet 配置為例進行講述领突,過濾器和監(jiān)聽器具有與之非常類似的特性 ):

編寫一個類繼承自 HttpServlet暖璧,將該類放在 classes 目錄下的對應包結構中,修改 web.xml君旦,在其中增加一個 Servlet 聲明澎办。這是最原始的方式;

編寫一個類繼承自 HttpServlet金砍,并且在該類上使用 @WebServlet 注解將該類聲明為 Servlet局蚀,將該類放在 classes 目錄下的對應包結構中,無需修改 web.xml 文件恕稠。

編寫一個類繼承自 HttpServlet琅绅,將該類打成 JAR 包,并且在 JAR 包的 META-INF 目錄下放置一個 web-fragment.xml 文件鹅巍,該文件中聲明了相應的 Servlet 配置千扶。web-fragment.xml 文件示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?xmlversion="1.0"encoding="UTF-8"?>

<web-fragment

????xmlns=http://java.sun.com/xml/ns/javaee

????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"version="3.0"

????xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

????http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"

????metadata-complete="true">

????<servlet>

????????<servlet-name>fragment</servlet-name>

????????<servlet-class>footmark.servlet.FragmentServlet</servlet-class>

????</servlet>

????<servlet-mapping>

????????<servlet-name>fragment</servlet-name>

????????<url-pattern>/fragment</url-pattern>

????</servlet-mapping>

</web-fragment>

從上面的示例可以看出,web-fragment.xml 與 web.xml 除了在頭部聲明的 XSD 引用不同之外昆著,其主體配置與 web.xml 是完全一致的县貌。

由于一個 Web 應用中可以出現(xiàn)多個 web-fragment.xml 聲明文件,加上一個 web.xml 文件凑懂,加載順序問題便成了不得不面對的問題煤痕。Servlet 規(guī)范的專家組在設計的時候已經考慮到了這個問題,并定義了加載順序的規(guī)則。

web-fragment.xml 包含了兩個可選的頂層標簽摆碉,<name> 和 <ordering>塘匣,如果希望為當前的文件指定明確的加載順序,通常需要使用這兩個標簽巷帝,<name> 主要用于標識當前的文件忌卤,而 <ordering> 則用于指定先后順序。一個簡單的示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

<web-fragment...>

????<name>FragmentA</name>

????<ordering>

????????<after>

????????????<name>FragmentB</name>

????????????<name>FragmentC</name>

????????</after>

????<before>

????????<others/>

????</before>

????</ordering>

????...

</web-fragment>

如上所示楞泼, <name> 標簽的取值通常是被其它 web-fragment.xml 文件在定義先后順序時引用的驰徊,在當前文件中一般用不著,它起著標識當前文件的作用堕阔。

在 <ordering> 標簽內部棍厂,我們可以定義當前 web-fragment.xml 文件與其他文件的相對位置關系,這主要通過 <ordering> 的 <after> 和 <before> 子標簽來實現(xiàn)的超陆。在這兩個子標簽內部可以通過 <name> 標簽來指定相對應的文件牺弹。比如:

1

2

3

4

<after>

????<name>FragmentB</name>

????<name>FragmentC</name>

</after>

以上片段則表示當前文件必須在 FragmentB 和 FragmentC 之后解析。<before> 的使用于此相同时呀,它所表示的是當前文件必須早于 <before> 標簽里所列出的 web-fragment.xml 文件张漂。

除了將所比較的文件通過 <name> 在 <after> 和 <begin> 中列出之外,Servlet 還提供了一個簡化的標簽 <others/>谨娜。它表示除了當前文件之外的其他所有的 web-fragment.xml 文件航攒。該標簽的優(yōu)先級要低于使用 <name> 明確指定的相對位置關系。

ServletContext 的性能增強

除了以上的新特性之外瞧预,ServletContext 對象的功能在新版本中也得到了增強∈赫現(xiàn)在,該對象支持在運行時動態(tài)部署 Servlet垢油、過濾器、監(jiān)聽器圆丹,以及為 Servlet 和過濾器增加 URL 映射等滩愁。以 Servlet 為例,過濾器與監(jiān)聽器與之類似辫封。ServletContext 為動態(tài)配置 Servlet 增加了如下方法:

ServletRegistration.Dynamic addServlet(String servletName,Class<? extends Servlet> servletClass)

ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)

ServletRegistration.Dynamic addServlet(String servletName, String className)

<T extends Servlet> T createServlet(Class<T> clazz)

ServletRegistration getServletRegistration(String servletName)

Map<String,? extends ServletRegistration> getServletRegistrations()

其中前三個方法的作用是相同的硝枉,只是參數(shù)類型不同而已;通過 createServlet() 方法創(chuàng)建的 Servlet倦微,通常需要做一些自定義的配置冠骄,然后使用 addServlet() 方法來將其動態(tài)注冊為一個可以用于服務的 Servlet瑞躺。兩個 getServletRegistration() 方法主要用于動態(tài)為 Servlet 增加映射信息,這等價于在 web.xml( 抑或 web-fragment.xml) 中使用 <servlet-mapping> 標簽為存在的 Servlet 增加映射信息。

以上 ServletContext 新增的方法要么是在 ServletContextListener 的 contexInitialized 方法中調用捷泞,要么是在 ServletContainerInitializer 的 onStartup() 方法中調用到推。

ServletContainerInitializer 也是 Servlet 3.0 新增的一個接口,容器在啟動時使用 JAR 服務 API(JAR Service API) 來發(fā)現(xiàn) ServletContainerInitializer 的實現(xiàn)類,并且容器將 WEB-INF/lib 目錄下 JAR 包中的類都交給該類的 onStartup() 方法處理嘉裤,我們通常需要在該實現(xiàn)類上使用 @HandlesTypes 注解來指定希望被處理的類,過濾掉不希望給 onStartup() 處理的類栖博。

HttpServletRequest 對文件上傳的支持

此前屑宠,對于處理上傳文件的操作一直是讓開發(fā)者頭疼的問題,因為 Servlet 本身沒有對此提供直接的支持仇让,需要使用第三方框架來實現(xiàn)典奉,而且使用起來也不夠簡單。如今這都成為了歷史丧叽,Servlet 3.0 已經提供了這個功能卫玖,而且使用也非常簡單。為此蠢正,HttpServletRequest 提供了兩個方法用于從請求中解析出上傳的文件:

Part getPart(String name)

Collection<Part> getParts()

前者用于獲取請求中給定 name 的文件骇笔,后者用于獲取所有的文件。每一個文件用一個 javax.servlet.http.Part 對象來表示嚣崭。該接口提供了處理文件的簡易方法笨触,比如 write()、delete() 等雹舀。至此芦劣,結合 HttpServletRequest 和 Part 來保存上傳的文件變得非常簡單,如下所示:

1

2

3

Part photo = request.getPart("photo");

photo.write("/tmp/photo.jpg");

// 可以將兩行代碼簡化為 request.getPart("photo").write("/tmp/photo.jpg") 一行说榆。

另外虚吟,開發(fā)者可以配合前面提到的 @MultipartConfig 注解來對上傳操作進行一些自定義的配置,比如限制上傳文件的大小签财,以及保存文件的路徑等串慰。其用法非常簡單,故不在此贅述了唱蒸。

需要注意的是邦鲫,如果請求的 MIME 類型不是 multipart/form-data,則不能使用上面的兩個方法神汹,否則將拋異常庆捺。

總結

Servlet 3.0 的眾多新特性使得 Servlet 開發(fā)變得更加簡單,尤其是異步處理特性和可插性支持的出現(xiàn)屁魏,必將對現(xiàn)有的 MVC 框架產生深遠影響滔以。雖然我們通常不會自己去用 Servlet 編寫控制層代碼,但是也許在下一個版本的 Struts 中氓拼,您就能切實感受到這些新特性帶來的實質性改變你画。

相關主題

JSR-000315 Java Servlet 3.0 規(guī)范:這里除了可以下載 Servlet 3.0 的規(guī)范文檔抵碟,還可以了解關于與該規(guī)范相關的一些其他信息。

GlassFish 項目主頁:可以在這里現(xiàn)在 GlassFish V3 版本撬即,這是 SUN 提供的 Java EE 6 規(guī)范的參考實現(xiàn)立磁。

Servlet 2.2 的新特征”(developerWorks,2000 年 12 月):討論 Servlet 2.2 一些新的比較重要的特征剥槐,并給出了一些簡單的例子來演示這些特征的用途及用法唱歧。

developerWorks Java 技術專區(qū):數(shù)百篇關于 Java 編程各個方面的文章。

評論

添加或訂閱評論粒竖,請先登錄注冊颅崩。

有新評論時提醒我

提交

最新的

歷史

熱門

最新的

最新的

歷史

熱門

2018 年 09 月 21 日

mrHe

mark

回復·0·報告濫用

2018 年 01 月 17 日

signorino

學習了!servlet3.0新特性蕊苗!注解代替?zhèn)鹘y(tǒng)配置文件是一個進步沿后,底層其實還是反射。

回復·0·報告濫用

2017 年 04 月 11 日

GongchuangSu

回復·0·報告濫用

2017 年 02 月 26 日

lookno

講的通俗易懂朽砰,果然是架構師

回復·0·報告濫用

2015 年 11 月 18 日

露秋du

學習

回復·0·報告濫用

2015 年 04 月 27 日

clmyouyx

學習學習了

回復·0·報告濫用

2014 年 02 月 13 日

王字兒倒著寫

為同一個頁面配置多個filter的時候尖滚,注解該怎么寫

回復·0·報告濫用

2010 年 11 月 18 日

Mill_zeng

我的印象中servlet是單實例,多線程的\nservlet2.5為什么會等待

回復·0·報告濫用

第一個評論

static.content.url=http://www.ibm.com/developerworks/js/artrating/

SITE_ID=10

Zone=Java technology, Web development

ArticleID=485182

ArticleTitle=Servlet 3.0 新特性詳解

publish-date=04232010

document.write('

url='+location.href.replace(/');

url=https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/index.html

developerWorks

站點反饋

我要投稿

投稿指南

報告濫用

第三方提示

關注微博

加入

ISV 資源 (英語)

大學合作

選擇語言

English

中文

日本語

Русский

Português (Brasil)

Espa?ol

??

技術文檔庫

dW 中國時事通訊

博客

活動

社區(qū)

開發(fā)者中心

視頻

訂閱源

軟件下載

Code patterns

聯(lián)系 IBM

隱私條約

使用條款

信息無障礙選項

反饋

Cookie 首選項

IBMCore.common.module.masthead.subscribe("ready", "customjs", setupCommentsPlugin).runAsap(setupCommentsPlugin);

function setupCommentsPlugin(){

//debugger;

//alert(userLinks);

var commentsInitInfo = {

contentId : $("div[class=metavalue]:contains('ArticleID=')").text().split("=")[1],

siteId :? $("div[class=metavalue]:contains('SITE_ID=')").text().split("=")[1],

pluginDivId : '#dw-icomments-container',

notifyElementId : "#comment_notification",

loginMessageDivId : "#dw-article-cmts-login",

totalCommentsDivId : "#nCmts",

isIdea:false

};

ContentComments.Setup(commentsInitInfo);

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末瞧柔,一起剝皮案震驚了整個濱河市漆弄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌造锅,老刑警劉巖撼唾,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哥蔚,居然都是意外死亡倒谷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門糙箍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渤愁,“玉大人,你說我怎么就攤上這事深夯『锪妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵塌西,是天一觀的道長。 經常有香客問我筝尾,道長捡需,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任筹淫,我火速辦了婚禮站辉,結果婚禮上呢撞,老公的妹妹穿的比我還像新娘。我一直安慰自己饰剥,他們只是感情好殊霞,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汰蓉,像睡著了一般绷蹲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上顾孽,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天祝钢,我揣著相機與錄音,去河邊找鬼若厚。 笑死拦英,一個胖子當著我的面吹牛,可吹牛的內容都是我干的测秸。 我是一名探鬼主播疤估,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼霎冯!你這毒婦竟也來了铃拇?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肃晚,失蹤者是張志新(化名)和其女友劉穎锚贱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體关串,經...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡拧廊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了晋修。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吧碾。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖墓卦,靈堂內的尸體忽然破棺而出倦春,到底是詐尸還是另有隱情,我是刑警寧澤落剪,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布睁本,位于F島的核電站,受9級特大地震影響忠怖,放射性物質發(fā)生泄漏呢堰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一凡泣、第九天 我趴在偏房一處隱蔽的房頂上張望枉疼。 院中可真熱鬧皮假,春花似錦、人聲如沸骂维。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽航闺。三九已至褪测,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間来颤,已是汗流浹背汰扭。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留福铅,地道東北人萝毛。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像滑黔,于是被迫代替她去往敵國和親笆包。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容