註解式:等價於web.xml註冊
@WebServlet(value(urlpatterns){},name,initParams={@WebInitParam(name,value)},loadOnStartup)
@WebFilter(value(servletNames){},dispatcherTypes={DispatcherType.xx})
@WebListener(name)
註冊servlet:若對於servlet採用了兩種方式同時註冊,則需要注意
1、若兩種方式的url-pattern值相同,則應用無法啓動
2、若兩種方式的url-pattern值不同,name相當於該servlet具有兩個url-pattern
註冊filter:若對於filter採用了兩種方式同時註冊,則需要注意
無論url-pattern的值是否相同,其都作爲兩個獨立的filter出現
註冊listener:若對於listener採用了兩種方式同時註冊,則需要注意
若對於listener採用了兩種方式同時進行註冊,其僅僅相當於一個listener
<web-app/>中的屬性metadata-complete的值若爲true,則表示三大組件的註冊方式,只有web.xml中的才起作用,忽略註解式註冊
文件上傳
Part part = request.getPart(name) //從multipart請求中獲取上傳的文件對象
part.write(path)
String header = part.getHeader("Content-Disposition") //獲取指定的頭部屬性
異步處理
這裏的異步處理指的是服務端的異步處理,區別於Ajax(客戶端的異步處理),實際就是將比較耗時的service調用交於子線程處理。
@WebServlet(asyncSupport=true) //開啓異步處理
// 主線程開啓
AsyncContext ac = request.startAsync() //獲取異步上下文對象
// 子線程{
運算
傳入上下文ac
運算完成
ac.complete() //第一種:通知主線程,異步子線程已經運行完成
// ac.dispatcher("xx.jsp") //第三種:將xx.jsp中的內容與子線程已輸出內容合併,並完成異步操作
}
//第二種:設置異步處理超時時長,自動銷燬request、異步上下文對象等,不管子線程是否完成所有工作
ac.setTimeout(int)
//ac.addListener(new AsyncListener{}) //爲異步對象添加異步監聽器
ac.start(子線程) //開啓異步上下文
// 主線程結束
對異步上下文對象ac的總結:
1、在異步子線程中使用ac.complete()方法:該方法用於結束異步操作,並將與當前異步對象相關的request與response對象銷燬
2、在異步servlet主線程中設置ac的超時時限,當超時時限到達時,異步對象及其相關的request和response對象銷燬
3、在異步子線程中使用ac.dispatch()方法:該方法在結束異步操作的同時,會將參數所指定的頁面內容包含到當前異步對象相關的標準輸出流中,即執行效果類似於RequestDispatcher對象的include()方法的執行效果
缺點:當在異步線程使用了相關對象,如request、response等時,主線程是無法快速結束的,處於阻塞狀態,客戶端會一直處於等待狀態,用戶體驗較差。
項目中實際用法:
將異步處理結果放置session中,使得主線程能夠快速處理完成,迅速響應。在其他地方獲取異步處理結果,如jsp中。
組件可插性
可定義web片段,打包成jar的形式,在其他web工程中引用即可直接使用
三大組件的動態註冊
所謂動態註冊,即Web應用在運行過程中通過代碼對Servlet、Filter、Listener進行註冊。
爲了系統安全考慮,動態註冊是有限制的:只能在應用啓動時進行,而不能在應用運行過程中進行註冊。這個應用啓動的時間點,可以通過ServletContextListener監聽器來把握。
@WebListener
MyServletContextListener implement ServletContextListener{
contextInitialized(ServletContextEvent sce){
//獲取ServletContext
ServletContext sc = sce.getServletContext()
//動態註冊Servlet
sc.addServlet(name,className/Servlet/...).addMapping(xx).setParamter(name,value)...
//動態註冊Filter
sc.addFilter(name,className/Filter/..)
.addMappingForUrlPatterns(dispatcherType,isMatchAfter,urlPatterns)
//動態註冊Listener
sc.addListener(classname/ListenerClass)
}
}