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?

站點地圖

市場

關(guān)閉

IBMIn Marketplace提交

我的 IBM

我的 IBM

IBM Developer

登錄

注冊

站點導(dǎo)航

站點導(dǎo)航

關(guān)閉

IBM developerWorks

學(xué)習(xí)

開發(fā)

社區(qū)

合作

市場

產(chǎn)品

產(chǎn)品

立即免費試用

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

云計算

認(rèn)知

認(rèn)知客戶互動

物聯(lián)網(wǎng)

行業(yè)解決方案

IT 基礎(chǔ)架構(gòu)

移動

IBM 安全

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

Watson

服務(wù)

企業(yè)咨詢服務(wù)

技術(shù)服務(wù)

融資

行業(yè)解決方案

培訓(xùn)與技能 (US)

行業(yè)

開發(fā)人員

developerWorks

PartnerWorld

云/AI 合作伙伴

支持

工作機(jī)會

IBM developerWorks

學(xué)習(xí)

開發(fā)

社區(qū)

合作

學(xué)習(xí)

Java technology

內(nèi)容

概覽

Servlet 3.0 新特性概述

異步處理支持

新增的注解支持

可插性支持

ServletContext 的性能增強(qiáng)

HttpServletRequest 對文件上傳的支持

總結(jié)

相關(guān)主題

評論

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)的基礎(chǔ)上提供了若干新特性用于簡化 Web 應(yīng)用的開發(fā)和部署。其中有幾項特性的引入讓開發(fā)者感到非常興奮,同時也獲得了 Java 社區(qū)的一片贊譽(yù)之聲:

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

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

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

下面我們將逐一講解這些新特性,通過下面的學(xué)習(xí),讀者將能夠明晰了解 Servlet 3.0 的變化,并能夠順利使用它進(jìn)行日常的開發(fā)工作。

異步處理支持

Servlet 3.0 之前,一個普通 Servlet 的主要工作流程大致如下:首先,Servlet 接收到請求之后,可能需要對請求攜帶的數(shù)據(jù)進(jìn)行一些預(yù)處理;接著,調(diào)用業(yè)務(wù)接口的某些方法,以完成業(yè)務(wù)處理;最后,根據(jù)處理的結(jié)果提交響應(yīng),Servlet 線程結(jié)束。其中第二步的業(yè)務(wù)處理通常是最耗時的,這主要體現(xiàn)在數(shù)據(jù)庫操作,以及其它的跨網(wǎng)絡(luò)調(diào)用等,在此過程中,Servlet 線程一直處于阻塞狀態(tài),直到業(yè)務(wù)方法執(zhí)行完畢。在處理業(yè)務(wù)的過程中,Servlet 資源一直被占用而得不到釋放,對于并發(fā)較大的應(yīng)用,這有可能造成性能的瓶頸。對此,在以前通常是采用私有解決方案來提前結(jié)束 Servlet 線程,并及時釋放資源。

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

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

對于使用傳統(tǒng)的部署描述文件 (web.xml) 配置 Servlet 和過濾器的情況,Servlet 3.0 為 和 標(biāo)簽增加了 子標(biāo)簽,該標(biāo)簽的默認(rèn)取值為 false,要啟用異步處理支持,則將其設(shè)為 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 進(jìn)行 Servlet 或過濾器配置的情況,這兩個注解都提供了 asyncSupported 屬性,默認(rèn)該屬性的取值為 false,要啟用異步處理支持,只需將該屬性設(shè)置為 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("進(jìn)入Servlet的時間:" + new Date() + ".");

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


????????//在子線程中執(zhí)行業(yè)務(wù)調(diào)用,并由其負(fù)責(zé)輸出響應(yīng),主線程退出

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

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


????????out.println("結(jié)束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è)務(wù)方法的執(zhí)行

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

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

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

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

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

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

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

????????}

????}

}

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

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

異步線程出錯時,調(diào)用 AsyncListener 的 onError(AsyncEvent event) 方法;

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

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

要注冊一個 AsyncListener,只需將準(zhǔn)備好的 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 的頂層標(biāo)簽 有一個 metadata-complete 屬性,該屬性指定當(dāng)前的部署描述文件是否是完全的。如果設(shè)置為 true,則容器在部署時將只依賴部署描述文件,忽略所有的注解(同時也會跳過 web-fragment.xml 的掃描,亦即禁用可插性支持,具體請看后文關(guān)于可插性支持的講解);如果不配置該屬性,或者將其設(shè)置為 false,則表示啟用注解支持(和可插性支持)。

@WebServlet

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

表 1. @WebServlet 主要屬性列表

屬性名類型描述

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

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

urlPatterns String[] 指定一組 Servlet 的 URL 匹配模式。等價于 <url-pattern> 標(biāo)簽。

loadOnStartup int 指定 Servlet 的加載順序,等價于 <load-on-startup> 標(biāo)簽。

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

asyncSupported boolean 聲明 Servlet 是否支持異步操作模式,等價于 <async-supported> 標(biāo)簽。

description String 該 Servlet 的描述信息,等價于 <description> 標(biāo)簽。

displayName String 該 Servlet 的顯示名,通常配合工具使用,等價于 <display-name> 標(biāo)簽。

下面是一個簡單的示例:

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 中配置相應(yīng)的 <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> 子標(biāo)簽。@WebInitParam 具有下表給出的一些常用屬性:

表 2. @WebInitParam 的常用屬性

屬性名類型是否可選描述

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

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

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

@WebFilter

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

表 3. @WebFilter 的常用屬性

屬性名類型描述

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

value String[] 該屬性等價于 urlPatterns 屬性。但是兩者不應(yīng)該同時使用。

urlPatterns String[] 指定一組過濾器的 URL 匹配模式。等價于 <url-pattern> 標(biāo)簽。

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

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

ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。

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

asyncSupported boolean 聲明過濾器是否支持異步操作模式,等價于 <async-supported> 標(biāo)簽。

description String 該過濾器的描述信息,等價于 <description> 標(biāo)簽。

displayName String 該過濾器的顯示名,通常配合工具使用,等價于 <display-name> 標(biāo)簽。

下面是一個簡單的示例:

1

2

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

public class LessThanSixFilter implements Filter{...}

如此配置之后,就可以不必在 web.xml 中配置相應(yīng)的 <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 標(biāo)注的類必須實現(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> 標(biāo)簽了。它等價的 web.xml 中的配置形式如下:

1

2

3

<listener>

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

</listener>

@MultipartConfig

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

表 5. @MultipartConfig 的常用屬性

屬性名類型是否可選描述

fileSizeThreshold int 是當(dāng)數(shù)據(jù)量大于該值時,內(nèi)容將被寫入文件。

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

maxFileSize long 是允許上傳的文件最大值。默認(rèn)值為 -1,表示沒有限制。

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

可插性支持

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

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

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

編寫一個類繼承自 HttpServlet,將該類放在 classes 目錄下的對應(yīng)包結(jié)構(gòu)中,修改 web.xml,在其中增加一個 Servlet 聲明。這是最原始的方式;

編寫一個類繼承自 HttpServlet,并且在該類上使用 @WebServlet 注解將該類聲明為 Servlet,將該類放在 classes 目錄下的對應(yīng)包結(jié)構(gòu)中,無需修改 web.xml 文件。

編寫一個類繼承自 HttpServlet,將該類打成 JAR 包,并且在 JAR 包的 META-INF 目錄下放置一個 web-fragment.xml 文件,該文件中聲明了相應(yīng)的 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 應(yīng)用中可以出現(xiàn)多個 web-fragment.xml 聲明文件,加上一個 web.xml 文件,加載順序問題便成了不得不面對的問題。Servlet 規(guī)范的專家組在設(shè)計的時候已經(jīng)考慮到了這個問題,并定義了加載順序的規(guī)則。

web-fragment.xml 包含了兩個可選的頂層標(biāo)簽,<name> 和 <ordering>,如果希望為當(dāng)前的文件指定明確的加載順序,通常需要使用這兩個標(biāo)簽,<name> 主要用于標(biāo)識當(dāng)前的文件,而 <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> 標(biāo)簽的取值通常是被其它 web-fragment.xml 文件在定義先后順序時引用的,在當(dāng)前文件中一般用不著,它起著標(biāo)識當(dāng)前文件的作用。

在 <ordering> 標(biāo)簽內(nèi)部,我們可以定義當(dāng)前 web-fragment.xml 文件與其他文件的相對位置關(guān)系,這主要通過 <ordering> 的 <after> 和 <before> 子標(biāo)簽來實現(xiàn)的。在這兩個子標(biāo)簽內(nèi)部可以通過 <name> 標(biāo)簽來指定相對應(yīng)的文件。比如:

1

2

3

4

<after>

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

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

</after>

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

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

ServletContext 的性能增強(qiáng)

除了以上的新特性之外,ServletContext 對象的功能在新版本中也得到了增強(qiáng)?,F(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)注冊為一個可以用于服務(wù)的 Servlet。兩個 getServletRegistration() 方法主要用于動態(tài)為 Servlet 增加映射信息,這等價于在 web.xml( 抑或 web-fragment.xml) 中使用 <servlet-mapping> 標(biāo)簽為存在的 Servlet 增加映射信息。

以上 ServletContext 新增的方法要么是在 ServletContextListener 的 contexInitialized 方法中調(diào)用,要么是在 ServletContainerInitializer 的 onStartup() 方法中調(diào)用。

ServletContainerInitializer 也是 Servlet 3.0 新增的一個接口,容器在啟動時使用 JAR 服務(wù) 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 已經(jīng)提供了這個功能,而且使用也非常簡單。為此,HttpServletRequest 提供了兩個方法用于從請求中解析出上傳的文件:

Part getPart(String name)

Collection<Part> getParts()

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

1

2

3

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

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

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

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

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

總結(jié)

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

相關(guān)主題

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

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

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

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

評論

添加或訂閱評論,請先登錄注冊。

有新評論時提醒我

提交

最新的

歷史

熱門

最新的

最新的

歷史

熱門

2018 年 09 月 21 日

mrHe

mark

回復(fù)·0·報告濫用

2018 年 01 月 17 日

signorino

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

回復(fù)·0·報告濫用

2017 年 04 月 11 日

GongchuangSu

回復(fù)·0·報告濫用

2017 年 02 月 26 日

lookno

講的通俗易懂,果然是架構(gòu)師

回復(fù)·0·報告濫用

2015 年 11 月 18 日

露秋du

學(xué)習(xí)

回復(fù)·0·報告濫用

2015 年 04 月 27 日

clmyouyx

學(xué)習(xí)學(xué)習(xí)了

回復(fù)·0·報告濫用

2014 年 02 月 13 日

王字兒倒著寫

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

回復(fù)·0·報告濫用

2010 年 11 月 18 日

Mill_zeng

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

回復(fù)·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

站點反饋

我要投稿

投稿指南

報告濫用

第三方提示

關(guān)注微博

加入

ISV 資源 (英語)

大學(xué)合作

選擇語言

English

中文

日本語

Русский

Português (Brasil)

Espa?ol

??

技術(shù)文檔庫

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);

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容