敘述Servlet API的討論
JSR-315發(fā)布了Servlet 3.0規(guī)范的公開預(yù)覽版,同時(shí)在GlassFish代碼分支上提供了參考實(shí)現(xiàn)。這次發(fā)布引發(fā)了人們對于專家組(ExpertGroup)為下一代Servlet API和整個(gè)JavaEE6平臺(tái)做出的各種選擇的爭論。
Servlet API一直處于風(fēng)口浪尖,從初期草稿開始,JSR315專家組致力于在類似便捷開發(fā)、插件性等領(lǐng)域完善和提高該規(guī)范,其***之一RajivMordani,這樣說道:
便捷開發(fā)(EaseofDevelopment):在早期草案中,我們添加了一些注解,允許你像POJO一樣寫Servlet 。但是在專家組的若干次討論和社區(qū)反饋之后,我們決定刪除像@GET,@POST這樣的方法層注解,保留doGet、doPos方法和擴(kuò)展HttpServlet 類。但是,那些重命名以更有效使用的最頂層注解仍然存在。@WebServlet 用于聲明一個(gè)Servlet ,@Servlet Filter聲明過濾器,@WebServlet Context Listener定義Servlet Context Listener。除了這些注解,像@Resource這種自Servlet 2.5就一直支持的注解則保持不變。
可插入性:構(gòu)建于Servlet 之上的Web框架在開發(fā)人員中很受歡迎,其中很多人提出了各種各樣的問題。為了更好地支持框架便于開發(fā)人員編寫web應(yīng)用,我們在Servlet 3.0規(guī)范中添加一些方式以幫助開發(fā)人員根據(jù)自身情況使用和管理框架。
異步處理:這是我們在Servlet 3.0規(guī)范中變化***的部分。在早期草案中,我們暫停、重新開始、確定了我們定義的語義。但是,在這之后,專家組對于如何解決異步處理的各種用例進(jìn)行了大量的討論,規(guī)范中做出的修改現(xiàn)在也可以解決各種問題。
RoyVanRijn表達(dá)了他對于早期草案中出現(xiàn)的一些特性的擔(dān)憂:
我更傾向于完全不使用針對GET/POST方法的注解,但是我發(fā)現(xiàn)JavaEE6規(guī)范提倡使用類似的注解,JSR-315的編寫者“別無選擇”(糟糕的借口)。我在本文中表達(dá)的觀點(diǎn)已經(jīng)發(fā)給了JSR組織,但至今沒有回應(yīng)。
我也找不到一名成員給出原因、解釋、澄清等等。最近JavaEE6規(guī)范發(fā)布公開預(yù)覽版,其中包含了對Servlet 3.0規(guī)范的引用,所以這會(huì)成為JavaEE6的一部分。但是我懇請他們花時(shí)間重新考慮關(guān)于注解的決定。
隨著規(guī)范公開預(yù)覽版的發(fā)布,來自Webtide的GregWilkins認(rèn)為該規(guī)范非常糟糕,是不和諧的專家組和有缺陷的流程的產(chǎn)物。他的主要觀點(diǎn)包括:
它代表了API設(shè)計(jì)上的一次思想實(shí)驗(yàn),不關(guān)注實(shí)現(xiàn)的復(fù)雜性、試用可行性和社區(qū)反饋。
要求測試實(shí)現(xiàn)的請求被拒絕了。
沒有公開的或者合理的機(jī)制來收集來自社區(qū)的需求和寶貴的社區(qū)咨詢。
一些模糊的需求(比如包裝的異步請求)在較晚時(shí)候包含進(jìn)來,沒有用例和用戶需求。
寫的非常糟糕,就像大多數(shù)JCP文檔一樣。
一些新的特性引起了安全隱患,并可能導(dǎo)致部署緩慢。
異步Servlet 的建議被改變了,與早期草案不同。最初的方法是JettyContinuations的結(jié)果,從2008年3月即可在Jetty-7pre-release中試用,已經(jīng)在很多框架和應(yīng)用中測試過,包括ometd、DWR、JSF和BlazeDS。
Greg總結(jié)說:
我相信在現(xiàn)在的預(yù)覽版中有明顯的錯(cuò)誤,這些缺陷已經(jīng)多的讓人很容易就可以發(fā)現(xiàn)。當(dāng)我從專家組收到關(guān)于這些問題的支持信息時(shí),我無法確信規(guī)范***的合法身份,我可能因?yàn)檫^于嚴(yán)厲而無法得到幫助了。
Rajiv對Greg的答復(fù)中指出:
在GlassFish中有相關(guān)實(shí)現(xiàn)。
他從沒看到過Greg的請求。
如果不喜歡新功能,可以禁止使用。
沒有明顯的證據(jù)表明部署會(huì)變慢。
異步Servlet 增加的方式更被社區(qū)所喜歡,他引用了專家組的郵件。
Rajiv也提到了來自RedHat的BillBurke寫的一篇博文,其中他批評了Jetty6中的異步Servlet 實(shí)現(xiàn)。
隨后,GregWilkins宣布他致力于Servlet 3.0異步Servlet 的一個(gè)實(shí)現(xiàn),他在博客上列舉了一些修正/擴(kuò)展和與專家組的持續(xù)討論。其中包括:
新的異步分發(fā)器類型(ASYNCDispatcherType),用于分發(fā)異步請求。
當(dāng)請求分發(fā)時(shí),isAsyncStarted()方法為false。
如果getReader()或者getOutputStream()已經(jīng)被調(diào)用,則調(diào)用startAsync()或者startAsync(request.response)時(shí)會(huì)拋出IllegalStateException異常。這可以把異步處理器限制到簡單的情況下。
如果通過startAsync(request,response)啟動(dòng)異步模式,在AsyncContext 上使用任何forward(...)方法都會(huì)有IllegalStateException異常。這避免了分發(fā)包裝器的復(fù)雜,但允許異步處理器使用包裝器。
forward(path)和forward(Context ,path)方法還沒有實(shí)現(xiàn)。
代碼可以從Jetty分支和Servlet -api分支中得到。
Grep談到了異步Servlet 的事情:
雖然還需要更多測試,但是這個(gè)代碼已經(jīng)實(shí)現(xiàn)了基本的異步行為,不需要很復(fù)雜的重新分發(fā)請求或者前遞方法。我相信這代表了3.0的合理折中方案。在我們從3.0的簡單子集里獲得經(jīng)驗(yàn)之后,如果需要更多的特性,可以添加到3.1中。
【編輯推薦】

















