使用Servlet3.0的注解进行配置步骤
启动类里面增加 @ServletComponentScan,进行扫描
新建一个Filter类,implements Filter,并实现对应的接口
@WebFilter 标记一个类为filter,被spring进行扫描
urlPatterns:拦截规则,支持正则
控制chain.doFilter的方法的调用,来实现是否通过放行
不放行,web应用resp.sendRedirect("/index.html") 或者 返回json字符串
package com.example.demo.filter; import com.example.demo.tools.JsonData; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang.StringUtils; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; //TODO 暂时不需要拦截器 Filter 所以为测试 Controller @WebFilter(urlPatterns = "/Controller/*",filterName = "测试") public class KnowledgeFilter implements Filter { private static final ObjectMapper objectMapper = new ObjectMapper(); /** * 容器加载的时候 * @param filterConfig * @throws ServletException */ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String token = req.getHeader("token"); if (StringUtils.isEmpty(token)){ token = req.getParameter("token"); } if (StringUtils.isEmpty(token)){ JsonData jsonData = JsonData.buildError("登录失败,token无效!",-2); String jsonStr = objectMapper.writeValueAsString(jsonData); renderJson(resp,jsonStr); }else { chain.doFilter(request,response); //TODO 判断是否合法 比如说判断此token是否在user表里面,如果是。。。。 } } private void renderJson(HttpServletResponse response,String json){ response.setCharacterEncoding("GBK"); response.setContentType("application/json"); try (PrintWriter writer = response.getWriter()){ writer.println(json); } catch (Exception e) { e.printStackTrace(); } } /** * 容器销毁的时候 */ @Override public void destroy() { } }
拦截器不生效常见问题:
- 是否有加@Configuration
- 拦截路径是否有问题 ** 和 *
- 拦截器最后路径一定要 /** 如果是目录的话则是 /*/
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 拦截器配置类 */ @Configuration public class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getLoginIntercepter()).addPathPatterns("/Controller1/*"); WebMvcConfigurer.super.addInterceptors(registry); } public LoginIntercepter getLoginIntercepter(){ return new LoginIntercepter(); } }
package com.example.demo.intercepter; import com.example.demo.tools.JsonData; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; public class LoginIntercepter implements HandlerInterceptor { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String token = req.getHeader("token"); if (StringUtils.isEmpty(token)){ token = req.getParameter("token"); } if (StringUtils.isEmpty(token)){ JsonData jsonData = JsonData.buildError("登录失败,token无效!",-2); String jsonStr = objectMapper.writeValueAsString(jsonData); renderJson(resp,jsonStr); return false; }else { return true; //TODO 判断是否合法 比如说判断此token是否在user表里面,如果是。。。。 } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } private void renderJson(HttpServletResponse response,String json){ response.setCharacterEncoding("GBK"); response.setContentType("application/json"); try (PrintWriter writer = response.getWriter()){ writer.println(json); } catch (Exception e) { e.printStackTrace(); } } }
和Filter过滤器的区别
Filter和Interceptor二者都是AOP编程思想的体现,功能基本都可以实现
拦截器功能更强大些,Filter能做的事情它都能做
Filter在只在Servlet前后起作用,而Interceptor够深入到方法前后、异常抛出前后等
filter依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。
在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。
Filter和Interceptor的执行顺序
过滤前->拦截前->action执行->拦截后->过滤后
补充知识点
如何配置不拦截某些路径?
registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/v1/pri/**")
//配置不拦截某些路径,比如静态资源
.excludePathPatterns("/**/*.html","/**/*.js");
/** * 拦截器配置类 */ @Configuration public class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getLoginIntercepter()).addPathPatterns("/Controller1/*") .excludePathPatterns("/Controller/register"); WebMvcConfigurer.super.addInterceptors(registry); } public LoginIntercepter getLoginIntercepter(){ return new LoginIntercepter(); } }
本文作者为DBC,转载请注明。