深入学习SSH框架《三:Servlet中配置过滤器Filter和异步过滤器》
2017-03-08 19:27
417 查看
在SSH应用程序中过滤器是一个很重要的角色,它有以下目的:
过滤器可以拦截访问资源的请求、资源的响应或者两个同时拦截,它们将以某种方式作用于这些请求或响应,过滤器可以检测和修改请求和响应,它们甚至可以拒绝和转发请求。其中过滤器也可编程式配置和在部署描述符中配置。过滤经常用在一下模块==》日志过滤器,验证过滤器,压缩和加密过滤器,错误处理过滤器。
1.过滤器的实现。
public class RequestLogFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Instant time = Instant.now(); StopWatch timer = new StopWatch(); try { timer.start(); chain.doFilter(request, response); } finally { timer.stop(); HttpServletRequest in = (HttpServletRequest)request; HttpServletResponse out = (HttpServletResponse)response; String length = out.getHeader("Content-Length"); if(length == null || length.length() == 0) length = "-"; System.out.println(in.getRemoteAddr() + " - - [" + time + "]" + " \"" + in.getMethod() + " " + in.getRequestURI() + " " + in.getProtocol() + "\" " + out.getStatus() + " " + length + " " + timer); } } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
2.部署过滤器。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>Filter Order Application</display-name> <filter> <filter-name>filterA</filter-name> <filter-class>com.wrox.FilterA</filter-class> <async-supported>true</async-supported> </filter> <filter-mapping> <filter-name>filterA</filter-name> <url-pattern>/*</url-pattern> <!-- <servlet-name>async</servlet-name> --> <dispatcher>ASYNC</dispatcher> <!-- <dispatcher>REQUEST</dispatcher> --> </filter-mapping> <filter> <filter-name>filterB</filter-name> <filter-class>com.wrox.FilterB</filter-class> </filter> <filter-mapping> <filter-name>filterB</filter-name> <url-pattern>/servletTwo</url-pattern> <url-pattern>/servletThree</url-pattern> </filter-mapping> <filter> <filter-name>filterC</filter-name> <filter-class>com.wrox.FilterC</filter-class> </filter> <filter-mapping> <filter-name>filterC</filter-name> <url-pattern>/servletTwo</url-pattern> </filter-mapping> </web-app>
其中要注意的是filter有一个支持异步属性,
<dispatcher>ASYNC</dispatcher>有效的类型还有REQUEST,FORWARD,INCLUDE,ERROR和ASYNC意思是该过滤器支持的
类型是请求、转发、包含、错误和异步类型,比如下面的示例:
@WebServlet(urlPatterns="/async", asyncSupported=true,name="async") public class AsynServlet extends HttpServlet { private static final long serialVersionUID = 1L; private HttpServletResponse responseAsyn; /** * @see HttpServlet#HttpServlet() */ public AsynServlet() { super(); // TODO Auto-generated constructor stub } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { responseAsyn=resp; resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("进入Servlet的时间:" + new Date() + "."); out.flush(); //在子线程中执行业务调用,并由其负责输出响应,主线程退出 final AsyncContext ctx = req.startAsync(); ctx.setTimeout(200000); new Work(ctx,responseAsyn).start(); out.println("结束Servlet的时间:" + new Date() + "."); out.flush(); } } class Work extends Thread{ private AsyncContext context; private HttpServletResponse response; public Work(AsyncContext context,HttpServletResponse response){ this.context = context; this.response=response; } @Override public void run() { try { Thread.sleep(2000);//让线程休眠2s钟模拟超时操作 PrintWriter wirter = context.getResponse().getWriter(); response.sendRedirect("/servletOne"); wirter.write("2s后调用servletOne"); wirter.flush(); context.complete(); } catch (InterruptedException e) { } catch (IOException e) { } } }
3.使用注解声明过滤器
package com.wrox; import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.xml.ws.Dispatch; import java.io.IOException; @WebFilter( urlPatterns={"/servlet/*","/servletone"}, servletNames={"servletTwo"}, dispatcherTypes={DispatcherType.ASYNC} ) public class FilterA implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Entering FilterA.doFilter().ASNY!!!"); chain.doFilter(request, response); System.out.println("Leaving FilterA.doFilter()."); } @Override public void init(FilterConfig config) throws ServletException { System.out.println("进入了过滤器的init方法==>"); } @Override public void destroy() { } }
4.过滤器的排序
由于注解标识的过滤器无法按照需要的顺序过滤,所以只能使用部署描述符进行过滤。排在越前的过滤器先执行,过滤器链就像一条流水线,一个出错了就不会继续执行过滤,实例代码.
5.过滤器处理异步请求。
import javax.servlet 4000 .AsyncContext; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.IOException; public class AnyRequestFilter implements Filter { private String name; @Override public void init(FilterConfig config) { this.name = config.getFilterName(); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Entering " + this.name + ".doFilter()."); chain.doFilter( new HttpServletRequestWrapper((HttpServletRequest)request), new HttpServletResponseWrapper((HttpServletResponse)response) ); if(request.isAsyncSupported() && request.isAsyncStarted()) { AsyncContext context = request.getAsyncContext(); System.out.println("Leaving " + this.name + ".doFilter(), async " + "context holds wrapped request/response = " + !context.hasOriginalRequestAndResponse()); } else System.out.println("Leaving " + this.name + ".doFilter()."); } @Override public void destroy() { } }
其中异步过滤器只有在标注了异步(@WebServlet(urlPatterns="/async", asyncSupported=true,name="async")或者
<filter>
<filter-name>filterA</filter-name>
<filter-class>com.wrox.FilterA</filter-class>
<async-supported>true</async-supported>
</filter>
才会执行
有关更多实例代码,在我的github地址
相关文章推荐
- 深入学习SSH框架《二:java编程式配置servlet和使用web.xml部署描述符配置servlet》
- jsp servlet中的过滤器Filter配置总结(转)
- jsp servlet中的过滤器Filter配置总结
- servlet和jsp页面过滤器Filter的作用及配置
- jsp servlet中的过滤器Filter配置总结
- servlet和jsp页面过滤器Filter的作用及配置
- Servlet3.0学习总结(二)——使用注解标注过滤器(Filter)
- java中servlet过滤器Filter学习(看网上资料 算是自己copy理解一遍吧)
- Jsp Servlet配置过滤器Filter
- 深入分析JavaWeb Item35 -- 过滤器Filter学习
- Servlet学习笔记(八):过滤器Filter详解
- SpringBoot学习教程 - 03 - 配置Servlet、Filter、Listener
- jsp servlet中的过滤器Filter配置总结
- jsp/servlet中的过滤器Filter配置总结
- Servlet3.0学习总结(二)——使用注解标注过滤器(Filter)
- Angular JS 学习笔记(自定义服务:factory,Promise 模式异步请求查询:$http,过滤器用法filter,指令:directive)
- jsp/servlet中的过滤器Filter配置总结
- Filter学习总结,顺便提及点servlet3.0异步filter和异步监听
- Servlet3.0学习总结(二)——使用注解标注过滤器(Filter)
- Servlet3.0学习总结(二)——使用注解标注过滤器(Filter)