注解式:等价于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)
}
}