使用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,转载请注明。