网站建设按什么收费,服务专业的网站制作服务,上线了建的网站免费吗,广州品牌网站开发Servlet3.0新特性全解
tomcat 7以上的版本都支持Servlet 3.0 Servlet 3.0 新增特性
注解支持#xff1b;Servlet、Filter、Listener无需在web.xml中进行配置#xff0c;可以通过对应注解进行配置#xff1b;支持Web模块#xff1b;Servlet异步处理#xff1b;文件上传AP…Servlet3.0新特性全解
tomcat 7以上的版本都支持Servlet 3.0 Servlet 3.0 新增特性
注解支持Servlet、Filter、Listener无需在web.xml中进行配置可以通过对应注解进行配置支持Web模块Servlet异步处理文件上传API简化
Servlet3.0的注解
WebServlet 修饰Servlet类用于部署该Servlet类。WebFilter修饰Filter类用于部署该Filter类WebInitParam与WebServlet或WebFilter注解连用为它们配置参数MultipartConfig修饰Servlet类指定该Servlet类负责处理multipart/form-data类型的请求主要用于处理上传文件ServletSecurity修饰Servlet类与JAAS(Java验证和授权API)有关的注解HttpConstrait与ServletSecurity连用HttpMethodConstrait与ServletSecurity连用
示例代码片 修饰过滤器Filter
WebFilter(filterNamelog,urlPatterns{/*},initParams{WebInitParam(nameencoding,valueGBK),WebInitParam(nameloginPage,value/login.jsp)})
public class MyFilter implements Filter {//内容省略......
}修饰Servlet
WebServlet(nametest,urlPatterns{/basic.do},initParams{WebInitParam(nameuserName,valuepeter),WebInitParam(nameage,value100)})
public class TestServlet extends HttpServlet{//内容省略....
}修饰监听器Listener:
WebListener
public class MyRequestListener implements ServletRequestListener{//内容省略...
}Servlet3.0的Web模块支持
原来一个web应用的任何配置都需要在web.xml中进行因此会使得web.xml变得很混乱而且灵活性差。现在可通过Web模块来部署管理它们。Web模块对应一个Jar包即Servlet 3.0可以将每个Servlet、Filter、Listener打成jar包然后放在WEB-INF\lib中。每个模块都有自己的配置文件这个配置文件的名称为 web-fragment.xml 。制作一个Servlet模块的步骤 正常编写Servlet并编译将此编译class文件及所在包通过jar包命令打成jar包将此jar包用winrar打开将META-INF中的manifest删除后添加 web-fragment.xml将此jar包放入WEB-INF\lib中即可 web-fragment.xml说明 web-fragment为根元素;name/name表示模块名称模块的唯一标识ordering/ordering定义模块加载顺序的标签当然可以不设置模块加载顺序beforeothers//before表示在所有模块前面加载第一个加载afternameA/name/after表示在A模块后面加载可以在里面部署listener、filter、servlet值得注意的是web.xml中用absolute-ordering标签指定的模块加载顺序将会覆盖web模块的web-fragment.xml文件中指定的加载顺序。 如何用myEclipse打jar包有些人不知道 右键你web项目里的编写的servlet或filter或listener类——Export…——JAR file——NEXT——(Browse)填写导出名字和存放位置——finish 这样就生成了我们需要的jar包了示例 servlet类代码片
WebServlet(value /hello/snow)
public class HelloWorldServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write(DO GEt... LocalDateTime.now().format(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss)));}}访问
servlet3.0提供的异步处理
提供异步原因
在以前的servlet中如果作为控制器的servlet调用了一个较为耗时的业务方法则servlet必须等到业务执行完后才会生成响应这使得这次调用成了阻塞式调用效率比较差
实现异步原理
重新开一个线程单独去调用耗时的业务方法。
配置servlet类成为异步的servlet类
通过注解asyncSupportedtrue实现通过web.xml配置
servletservlet-nametest1/servlet-nameservlet-classcom.zrgk.servlet.AsyncServlet/servlet-classasync-supporedtrue/async-suppored /servletservlet-mappingservlet-nametest1/servlet-nameurl-pattern/basic.do/url-pattern/servlet-mapping具体实现
java代码
WebServlet(nameAsyncServlet,urlPatterns{/testAsyn.do},asyncSupportedtrue)
public class AsyncServlet extends HttpServlet{ public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{ //解决乱码request.setCharacterEncoding(GBK); response.setContentType(text/html;charsetGBK); //通过request获得AsyncContent对象AsyncContext actx request.startAsync(); //重点方法**//设置异步调用超时时长actx.setTimeout(30*3000); //启动异步调用的线程actx.start(new MyThread(actx));//重点方法**// 直接输出到页面的内容(不等异步完成就直接给页面)//但这些内容必须放在标签内,否则会在页面输出错误内容这儿反正我测试是这样具体不知对不对PrintWriter out response.getWriter();out.println(h1不等异步返回结果就直接返到页面的内容/h1); out.flush(); }
} //异步处理业务的线程类
public class MyThread implements Runnable {private AsyncContext actx; //构造public MyThread(AsyncContext actx){ this.actx actx; } public void run(){ try{ //等待5秒模拟处理耗时的业务Thread.sleep(4*1000); //获得request对象添加数据给页面ServletRequest req actx.getRequest();req.setAttribute(content,异步获得的数据);//将请求dispath到index.jsp页面该页面的session必须设为falseactx.dispatch(/index.jsp); }catch(Exception e){e.printStackTrace();} }
} 页面代码页头里session设为false表时该页面不会再创建session
% page languagejava importjava.util.* pageEncodingutf-8 sessionfalse%
%
String path request.getContextPath();
String basePath request.getScheme()://request.getServerName():request.getServerPort()path/;
%
html bodya href%basePath%/testAsyn.do测试异步调用/a异步结果${content}/body
/html异步监听器
异步监听器用来监听异步Servlet的异步处理事件通过实现AsyncListener接口实现代码如下
public class MyAsyncListener implements AsyncListener{//异步调用完成时触发Overridepublic void onComplete(AsyncEvent event) throws IOException {// 省略.... }//异步调用出错时触发Overridepublic void onError(AsyncEvent event) throws IOException {// 省略.... }//异步调用开始触发Overridepublic void onStartAsync(AsyncEvent event) throws IOException {// 省略.... }//异步调用超时触发Overridepublic void onTimeout(AsyncEvent event) throws IOException {// 省略.... }} 还需要在异步Servlet里注册异步监听器即添加如下代码即可 actx.addListener(new MyAsyncListener()); Filter异步调用与Servlet一样。
改进的ServletAPI(上传文件) 改进内容 HttpServletRequest增加了对上传文件的支持ServletContext允许通过编程的方式动态注册Servlet、Filter HttpServletRequest提供了如下两个方法处理文件的上传 Part getPart(String name) 根据名称获取文件上传域 CollectionPart getParts() 获取所有文件上传域 上传文件时一定要为表单域设置enctype属性它表示表单数据的编码方式有如下三个值 application/x-www-form-urlencoded 默认它只处理表单里的value属性值它会将value值处理成URL编码方式。如果此时表单域里有上传文件的域type”file”则只会获取该文件在上传者电脑里的绝对路径串该串没什么实际意义。 multipart/form-data 此处编码方式会以二制流的方式来处理表单数据此时会将文件内容也封装到请求参数里。texst/plain 当表单的action属性为mailto:URL的形式时比较方便主要适用于直接通过表单发送邮件的方式 上传文件的Servlet需要加上MultipartConfig注解 通过request获取的Part对象就可以操作文件域了 示例
WebServlet(nameuploadServlet,urlPatterns/upload.do)
MultipartConfig
public class UploaderServlet extends HttpServlet {public void service(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{//获得Par对象每个Part对象对应一个文件域Part part request.getPart(file);long size part.getSize(); //获取上传文件大小String info part.getHeader(content-disposition);//获得包含原始文件名的字符串//获取原始文件名String fileName info.substring(info.indexOf(filename\)10,info.length()-1);//将文件上传到某个位置part.write(getServletContext().getRealPath(/uploadFiles)/fileName);}
}ServletContext提供了如下方法动态注册Servlet、Filter addServlet(); 动态注册Servlet addFilter(); 动态注册Filter addListener(); 动态注册Listener setInitParameter(String name ,String value); 为Web应用设置初始化参数。