参考:http://blog.csdn.net/chenleixing/article/details/44573495 http://haohaoxuexi.iteye.com/blog/1750680
以前在学习时一直搞不清这两者的区别,以为过滤器是servlet中的,拦截器是sPRingmvc的,后来在做一个登录拦截的时候,发现两者都可以实现,所以稍微的终结了一下。 下图是过滤器和拦截联合使用时的请求的流程
过滤器是javaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
拦截器是被包裹在过滤器之中的。
@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion");}a.preHandle()这个方法是在过滤器的chain.doFilter(request, response)方法的前一步执行,也就是在 [System.out.println(“before…”)][chain.doFilter(request, response)]之间执行。 b.preHandle()方法之后,在return ModelAndView之前进行,可以操控Controller的ModelAndView内容。 c.afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在[chain.doFilter(request, response)][System.out.println(“after…”)]之间执行。
下面是具体的使用方式
1.编写一个java类,实现Filter接口
package cn.note.web;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.context.applicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import cn.tedu.note.service.UserService;public class ACLFilter implements Filter{ private ServletContext sc; private ApplicationContext ctx; private UserService userService; /** * 过滤器初始化代码 */ public void init(FilterConfig cfg) throws ServletException { sc= cfg.getServletContext(); //获取Spring容器 ctx=WebApplicationContextUtils.getWebApplicationContext(sc); //从容器中获取 UserService 对象 userService=ctx.getBean("userService",UserService.class); } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException { chain.doFilter(request, response); } public void destroy() { }}2.doFilter中实现拦截
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response =(HttpServletResponse) res; String path=request.getRequestURI(); //System.out.println(path); path = path.substring( path.indexOf('/', 1)); //System.out.println("trim path:"+path); if(path.matches(".*/edit//.html$")){ checkLogin(request,response,chain); return; } if(path.matches(".(note).*//.do$")){ checkDotDo(request,response,chain); return; } chain.doFilter(request, response); }3.将过滤器添加到web程序中 在web.xml中添加如下的配置
<filter> <filter-name>acl</filter-name> <filter-class> cn.note.web.ACLFilter </filter-class> </filter> <filter-mapping> <filter-name>acl</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>4.打包部署。。 这样一个简单的过滤器就已经完成了。其最核心的其实也就是dofilter里面对过滤条件的判断
下面是拦截器的使用 和过滤器一样 第一步:首先 implements HandlerInterceptor接口 第二步:由于我要在执行controller之前拿到cookie的value 所以我在preHandle方法里面实现代码 第三步:与spring的项目整合
package com.jt.web.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import com.jt.common.service.HttpClientService;import com.jt.common.util.CookieUtils;import com.jt.web.controller.UserController;import com.jt.web.controller.UserThreadLocal;import com.jt.web.pojo.User;public class CartInterception implements HandlerInterceptor{ @Autowired private HttpClientService httpClientService; private static final ObjectMapper MAPPER=new ObjectMapper(); //在执行整个controller完成渲染之后(数据完成绑定后,即将就要转发了),转向页面之前 @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } //在执行controller之后 @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub } //在执行controller方法前执行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse arg1, Object arg2) throws Exception { //从cookie中获取ticket String ticket=CookieUtils.getCookieValue(request, UserController.UsercookieName); if(StringUtils.isEmpty(ticket)){ UserThreadLocal.setUser(null); }else{ //成功获取ticket String url="http://sso.jt.com/user/query/"+ticket; String jsonData=httpClientService.doGet(url, "utf-8"); if(StringUtils.isNoneEmpty(jsonData)){ //成功获取jsonData JsonNode jsonNode=MAPPER.readTree(jsonData); String data=jsonNode.get("data").asText(); User user=MAPPER.readValue(data, User.class); UserThreadLocal.setUser(user); }else{ UserThreadLocal.setUser(null); } } return true;//默认不放行,日常的情况下,不管对错都放行 }}在springmvc的配置文件中添加
<!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 指定拦截的映射 ,**拦截后面的多级目录--> <mvc:mapping path="/cart/**"/> <!-- 指定实现类 --> <bean class="com.jt.web.interceptor.CartInterception"></bean> </mvc:interceptor> </mvc:interceptors>发布部署即可。
新闻热点
疑难解答