在Java中,过滤器(Filter)和拦截器(Interceptor)是用于对请求进行预处理或后处理的组件。它们可以用于实现一些共同的功能,例如身份验证、数据转换、日志记录等。
过滤器(Filter)
Java Servlet规范中定义的组件,它可以在请求到达Servlet之前对请求和响应进行处理。过滤器可以在web.xml文件中进行配置,并可以通过URL模式指定对哪些请求进行过滤。过滤器可以对请求参数、请求头、请求路径等进行检查和修改。过滤器可以被链式调用,即多个过滤器可以按照一定的顺序进行调用。
拦截器(Interceptor)
是Spring框架中的概念,它是一种更加通用和灵活的请求处理组件。拦截器可以在请求到达Controller之前和之后对请求进行处理。拦截器可以通过实现HandlerInterceptor接口来定义自己的逻辑,并可以通过配置文件或注解来指定拦截的请求路径。拦截器可以对请求进行预处理和后处理,也可以决定是否执行下一步的处理。
过滤器和拦截器的区别
主要有以下几点:
- 过滤器基于Servlet规范,拦截器是Spring框架提供的特性。
- 过滤器可以在请求到达Servlet之前进行处理,拦截器可以在请求到达Controller之前和之后进行处理。
- 过滤器只能通过web.xml文件进行配置,拦截器可以通过配置文件或注解进行配置。
- 过滤器可以对请求和响应进行修改,拦截器更加灵活,可以在请求处理过程中进行更多的自定义处理。
应用:
过滤器与拦截器在登录校验的应用中,可以加上wt令牌进行校验,以防止对web资源的非法访问,在访问web资源时,只有先进行登录操作,才能够对内容进行访问,如果不登录就直接访问,将会被过滤器或者拦截器拦截。
过滤器:
@Slf4j
@WebFilter("/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse) servletResponse;
// 获取url
String requestURL = request.getRequestURL().toString();
// 验证是否为登录操作
if(requestURL.contains("login")){
log.info("登录操作,放行");
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// 获取token(JWT令牌)
String token = request.getHeader("token");
if(StringUtils.hasLength(token)){
// jwt存在,验证jwt
try{
JwtUtils.parseJWT(token);
filterChain.doFilter(servletRequest, servletResponse);
log.info("jwt令牌校验成功,放行");
return;
}catch (Exception e){
e.printStackTrace();
log.info("jwt令牌校验失败");
Result error = Result.error("NOT_LOGIN");
String s = JSONObject.toJSONString(error);
response.getWriter().write(s);
return;
}
}else {
// jwt不存在
log.info("jwt不存在");
Result error = Result.error("NOT_LOGIN");
String s = JSONObject.toJSONString(error);
response.getWriter().write(s);
return;
}
}
}
拦截器:
与过滤器不同的是,实现拦截器时通常还会增加一个配置类来注册一个拦截器
配置类:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginCheckIntercetpor loginCheckIntercetpor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckIntercetpor).addPathPatterns("/**").excludePathPatterns("/login");
}
}
拦截器:
@Slf4j
@Component
public class LoginCheckIntercetpor implements HandlerInterceptor {
//目标资源执行前执行,返回true放行,返回false不放行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURL = request.getRequestURL().toString();
// 验证是否为登录操作
if(requestURL.contains("login")){
log.info("登录操作,放行");
return true;
}
// 获取token(JWT令牌)
String token = request.getHeader("token");
if(StringUtils.hasLength(token)){
// jwt存在,验证jwt
try{
JwtUtils.parseJWT(token);
log.info("jwt令牌校验成功,放行");
return true;
}catch (Exception e){
e.printStackTrace();
log.info("jwt令牌校验失败");
Result error = Result.error("NOT_LOGIN");
String s = JSONObject.toJSONString(error);
response.getWriter().write(s);
return false;
}
}else {
// jwt不存在
log.info("jwt不存在");
Result error = Result.error("NOT_LOGIN");
String s = JSONObject.toJSONString(error);
response.getWriter().write(s);
return false;
}
}
//目标资源执行后执行,返回true放行,返回false不放行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("posthandle...");
}
//所有视图渲染完毕后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("aftercompletion...");
}
}
执行容器:
过滤器(Filter)在Servlet容器中执行,拦截器(Interceptor)在Spring容器中执行。拦截器更加灵活,可以访问Spring容器中的Bean,而过滤器则不能。