过滤器(Filter)和拦截器(Interceptor)是在Web开发中常用的两种概念,用于对HTTP请求和响应进行处理和控制。它们通常用于实现一些通用的功能,比如身份验证、日志记录、安全性检查等。
1、二者的不同点:
过滤器更适用于基于Servlet的应用,而拦截器则更适合于使用Spring MVC的项目
- 过滤器是Servlet规范提供的一种机制,主要用于在HTTP请求和响应的处理过程中进行拦截和处理。过滤器可以对请求和响应进行修改、增加或删除一些属性、头信息等。它们可以用于全局的过程,比如在请求进入Servlet之前进行预处理,或者在响应返回给客户端之前进行后处理。
- 拦截器是Spring框架提供的一种机制,用于在Spring MVC框架中对HTTP请求进行拦截和处理。拦截器可以更细粒度地控制请求的处理流程,例如在进入Controller之前或之后执行一些操作。
2、Filter
使用步骤:
1)定义Filter:定义一个类,实现Filter接口,并重写其所有方法。
这里以实现登陆验证功能为例:
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 将通用的 ServletRequest 转换为 HttpServletRequest
HttpServletRequest req = (HttpServletRequest) servletRequest;
// 将通用的 ServletResponse 转换为 HttpServletResponse
HttpServletResponse resp = (HttpServletResponse) servletResponse;
// 1、获取请求url
String url = req.getRequestURI().toString();
// 2、判断请求url中是否包含login,如果包含,说明是登录操作,放行。
if (url.contains("login")){
//放行操作
filterChain.doFilter(servletRequest,servletResponse);
return;
}
// 3、获取请求头中的令牌(token)。
String jwt = req.getHeader("token");
// 4、判断令牌是否存在,如果不存在,返回错误结果(未登录)。
if (!StringUtils.hasLength(jwt)){
Result error = Result.error("NOT LOGIN");
//手动转换,将对象转换为json格式 <-----阿里巴巴fastjson
String notLogin = JSONObject.toJSONString(error);
//将该字符串响应给前端
resp.getWriter().write(notLogin);
return;
}
// 5、解析token,如果解析失败,返回错误结果(未登录)。
try {
JwtUtils.parseJWT(jwt);
}catch (Exception e){//解析失败
e.printStackTrace();
Result error = Result.error("NOT LOGIN");
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return;
}
// 6、放行。
filterChain.doFilter(servletRequest,servletResponse);
}
}
首先,在过滤器中实现 doFilter
方法时,通常需要对传入的请求(ServletRequest
)和响应(ServletResponse
)进行类型转换,以便能够使用更多的 Servlet API 功能。所以这里的前两行代码将通用的 ServletRequest
和 ServletResponse
转换为 HttpServletRequest
和 HttpServletResponse
,以便可以访问更丰富的 HTTP 请求和响应的功能。
之后按照登录认证的五步走:1、获取请求url;2、判断请求url中是否包含login,如果包含,说明是登录操作,放行;3、获取请求头中的令牌(此处我的指定令牌名为token);4、判断令牌是否存在,如果不存在,返回错误结果(未登录);5、解析token,如果解析失败,返回错误结果(未登录)。
其中JwtUtils是用于实现jwt生成和解码的工具类,前一篇文章有写。
2)配置Filter:
Filter类上加@WebFilter注解,配置拦截资源的路径。引导类上加@ServletComponentScan开启Servlet组件支持。
@WebFilter注解用于对过滤器进行配置,其后的(urlPatterns = "/*")是指定要拦截的URL模式,"/*"代表拦截全部。
3、Interceptor
1)定义Interceptor:定义一个类,实现Interceptor接口,并重写其preHandle方法
同样以实现登陆验证功能为例:
@Component
public class LoginCheckinterceptor implements HandlerInterceptor {
//快捷键ctrl+o 对方法进行重写
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
//目标资源方法执行前执行,返回true:放行,返回false:不放行
// 1、获取请求url
String url = req.getRequestURI().toString();
// 2、判断请求url中是否包含login,如果包含,说明是登录操作,放行。
if (url.contains("login")){
//放行操作
return true;
}
// 3、获取请求头中的令牌(token)。
String jwt = req.getHeader("token");
// 4、判断令牌是否存在,如果不存在,返回错误结果(未登录)。
if (!StringUtils.hasLength(jwt)){
Result error = Result.error("NOT LOGIN");
//手动转换,将对象转换为json格式 <-----阿里巴巴fastjson
String notLogin = JSONObject.toJSONString(error);
//将该字符串响应给前端
resp.getWriter().write(notLogin);
return false;
}
// 5、解析token,如果解析失败,返回错误结果(未登录)。
try {
JwtUtils.parseJWT(jwt);
}catch (Exception e){//解析失败
e.printStackTrace();
Result error = Result.error("NOT LOGIN");
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return false;
}
// 6、放行。
return true;
}
@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");
}
}
4、方法重写方面需注意
在 Java Web 开发中,Filter 和 Interceptor 都是用于处理请求和响应的中间件,但它们在使用和实现方面有一些区别。
Filter:
- 在 Java Servlet 规范中,Filter 是一个标准的接口,为处理请求和响应提供了通用的方式。
- Filter 需要实现
javax.servlet.Filter
接口,它有三个主要方法:init
、doFilter
和destroy
。 doFilter
方法是必须要实现的,用于编写过滤逻辑。可以对请求和响应进行修改或处理。- Filter 的方法需要显式地调用
chain.doFilter(request, response)
来继续请求链的处理。
Interceptor:
- 在 Spring MVC 中,Interceptor 是 Spring 框架提供的一种机制,用于处理请求和响应。
- Interceptor 需要实现
org.springframework.web.servlet.HandlerInterceptor
接口,它有三个方法:preHandle
、postHandle
和afterCompletion
。 - 我们需要根据需要重写这些方法来实现预处理、后处理和完成处理逻辑。
- Interceptor 的方法不需要显式地调用下一个拦截器或处理链。