概念:Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。
快速入门
定义FIlter类
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化方法");
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("放行前执行的逻辑");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("放行后执行的逻辑");
}
@Override
public void destroy() {
System.out.println("销毁方法执行的逻辑");
Filter.super.destroy();
}
}
配置Filter
Filter类上加 @WebFilter 注解,配置拦截资源的路径。
引导类上加 @ServletComponentScan 开启Servlet组件支
@SpringBootApplication
@ServletComponentScan
public class WebManagementApplication {
public static void main(String[] args) {
SpringApplication.run(WebManagementApplication.class, args);
}
}
Filter拦截路径
拦截具体路径 | /login | 只有访问 /login 路径时,才会被拦截 |
目录拦截 | /emps/* | 访问/emps下的所有资源,都会被拦截 |
拦截所有 | /* | 访问所有资源,都会被拦截 |
Filter的执行流程:请求 --> 放行前逻辑 --> 放行 --> 资源 --> 放行后逻辑
过滤器链: 一个web应用中,配置了多个过滤器,就形成了一个过滤器链
登录验证Filter流程
- 获取请求url。
- 判断请求url中是否包含login,如果包含,说明是登录操作,放行。
- 获取请求头中的令牌(token)。
- 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
- 解析token,如果解析失败,返回错误结果(未登录)
- 放行
Filter类
@Slf4j
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setCharacterEncoding("UTF-8");
//获取url
String url = httpServletRequest.getRequestURI();
log.info("url:{}",url);
//判断是否包含login请求,是就放行
if (url.contains("login")) {
filterChain.doFilter(request,response);
return;
}
//获取token
String token = httpServletRequest.getHeader("token");
//判断token是否存在
if (!StringUtils.hasLength(token)) {
Result error = Result.error("未登录");
String noLogin = JSONObject.toJSONString(error);
httpServletResponse.getWriter().write(noLogin);
return;
}
//解析token是否存在
try {
JwtUtils.parseJwt(token);
}catch (Exception e){
e.printStackTrace();
Result noLogin = Result.error("未登录");
String s = JSONObject.toJSONString(noLogin);
httpServletResponse.getWriter().write(s);
return;
}
log.info("令牌合法,放行:{}",token);
filterChain.doFilter(request,response);
}
}
JwtUtils类
@Component
public class JwtUtils {
private static final String SIGN_KEY = "laohuang";
//生成
public static String generateJwt(Map<String,Object> claims){
return Jwts.builder()
.setClaims(claims) //自定义内容
.signWith(SignatureAlgorithm.HS256, SIGN_KEY)//签名算法
.setExpiration(new Date(System.currentTimeMillis() + 12 * 3600)) //有效期
.compact();
}
//解析
public static Claims parseJwt(String token){
return Jwts.parser()
.setSigningKey(SIGN_KEY)
.parseClaimsJws(token)
.getBody();
}
}
结果