Servlet之所以沒(méi)有像之前的ejb那樣被受到那么多的詬病,是因?yàn)閟ervlet的設(shè)計(jì)確實(shí)非常好。在最新的Java EE6版本里,這么多年都沒(méi)有多少重大改動(dòng)的Servlet終于添加了很多新的功能。下面我們一個(gè)一個(gè)來(lái)看
自從java 5增加了annotation后,現(xiàn)在annotation已經(jīng)廣范用于各種框架,確實(shí)減少了很多的編寫(xiě)配置文件的工作。現(xiàn)在終于可以不用寫(xiě)web.xml,只要通過(guò)WebServlet, WebFilter, WebListener這幾個(gè)annotation就可以輕易的配置Servlet, filter和listener了。而且, web.xml已經(jīng)是可選的了,就算沒(méi)有它,也一樣運(yùn)行。
Servlet 3.0 新添加了一個(gè)類AsyncContext,可以通過(guò)ServletRequest活得。如果調(diào)用了ServletRequest的startAsync(),那么這個(gè)請(qǐng)求將會(huì)被異步處理,這意味著即使當(dāng)前的線程執(zhí)行結(jié)束,也不會(huì)給發(fā)送會(huì)響應(yīng),而是要等到AsyncContext的complete()方法被調(diào)用。通過(guò)AsyncContext,一樣可以取到ServletRequest,和ServletResponse對(duì)象,這意味著即使最初Servlet執(zhí)行的線程執(zhí)行結(jié)束,也一樣可以取到那次請(qǐng)求數(shù)據(jù)和返回客戶端數(shù)據(jù)。
在通常的Servlet設(shè)計(jì)中,servlet容器會(huì)為每個(gè)客戶端的請(qǐng)求分配一個(gè)線程,如果處理請(qǐng)求的過(guò)程中需要等待某種很慢的資源,在訪問(wèn)量大的時(shí)候,可能導(dǎo)致servlet容器的線程池耗光,從而無(wú)法響應(yīng)后續(xù)的請(qǐng)求。有了異步處理的servlet之后,可以將這些線程解放出來(lái),把它們放到一個(gè)隊(duì)列里等待。比起線程,普通的對(duì)象還是要占用較少資源的。
Web容器加載的時(shí)候,會(huì)掃描WEB-INF/lib下的jar, 如果這個(gè)jar的有META-INF/web-fragment.xml,那這這個(gè)web-fragment.xml內(nèi)的配置信息也會(huì)被使用。這個(gè)功能對(duì)做web框架很有用。很多web框架都是通過(guò)自定義自己的servlet, filter或listener實(shí)現(xiàn)的,現(xiàn)在,框架的開(kāi)發(fā)者可以將默認(rèn)的配置放到自己的jar里,使用者只要把jar丟到WEB-INF/lib/目錄下就可以使用框架了,更加方便。通過(guò)web-fragment, 可以更容易的對(duì)一個(gè)war實(shí)現(xiàn)部署上的模塊化。
這個(gè)功能的意思是指,應(yīng)用程序可以在運(yùn)行時(shí)注冊(cè)servlet, filter和listener。ServletContext里多了addFilter(), addServlet()等方法,來(lái)給用戶調(diào)用。很奇怪的是,我只看到注冊(cè)組件的,沒(méi)有看到注銷組件的,如果只能加不能減的話,那這一功能估計(jì)只能看作是通過(guò)xml配置的另一種方法。
如果WEB-INF/lib下有某個(gè)jar文件包含META-INF/services/javax.servlet.ServletContainerInitializer文件,且該文本文件內(nèi)的類名所對(duì)應(yīng)的類實(shí)現(xiàn)了javax.servlet.ServletContainerInitializer接口,那么這個(gè)類所實(shí)現(xiàn)的該接口方法會(huì)在容器啟動(dòng)時(shí)被調(diào)用。 這個(gè)接口方法是onStartup(java.util.Set<>?>> c, ServletContext ctx) , 其中c是一個(gè)類的集合。你必須在這個(gè)方法上使用HandlesTypes annation,這個(gè)annotation會(huì)指定一些類,而所有實(shí)現(xiàn)了,集成了或標(biāo)注了這個(gè)些類的類會(huì)做成一個(gè)結(jié)合作為參數(shù)傳給onStartup方法。說(shuō)起來(lái)復(fù)雜,寫(xiě)起來(lái)簡(jiǎn)單:?>
@HandlesTypes({A.class})
public void onStartup(Set<Class<?>> c, ServletContext ctx){
//
}
對(duì)于上面的例子,c集合里的類要么實(shí)現(xiàn)了A,要么集成了A,要么標(biāo)注了A。
看來(lái)這個(gè)功能還是為了自定義框架用的。
以前Session cookie的名字一般固定為JSESSIONID,現(xiàn)在通過(guò)ServletContext可以獲得SessionCookieConfig對(duì)象,而該對(duì)象可以讓我們自定義session cookie的名字等屬性。
編寫(xiě)接受上傳文件的程序更容易了,通過(guò)HttpServletRequest對(duì)象可以獲得Part對(duì)象,每一個(gè)Part代表了上傳的一個(gè)文件。調(diào)用Part.write(String)方法,可以很輕松的把上傳的文件保存為參數(shù)指定的文件名。
可以看出,這些更改,都無(wú)疑使Servlet編程更容易更靈活了。所以還是很期待能在項(xiàng)目中使用Servlet 3.0 。
相關(guān)文章:
聯(lián)系客服