过滤器(Filter):
概念:Filter过滤器,是javaWeb三大组件(Servlet,Filter,Listener)之一。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
过滤器一般完成一些通用操作,比如:登陆校验,统一编码处理,敏感字符处理等。
过滤器快速入门:
1.定义filter:定义一个类,实现filter接口,并重写其所有方法。
2.配置filter:filter类上加@webfilter注解,配置拦截资源的路径。引导类上加@ServletComponentScan开启Servlet组件支持.注意是引导类,也就是启动类上面的注解。
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
@Override //初始化方法,只调用一次
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init 初始化方法执行");
}
@Override //拦截到请求之后调用,调用多次
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截到了请求");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override //销毁方法,只调用一次
public void destroy() {
System.out.println(" destroy 销毁方法执行");
}
}
@SpringBootApplication
@ServletComponentScan //开启了对servlet组件的支持
public class TliasWebApplication {
public static void main(String[] args) {
SpringApplication.run(TliasWebApplication.class, args);
}
}
过滤器的(执行流程,拦截路径,过滤器链):
在过滤器中的非常重要的操作,放行操作,FilterChain 就是执行的放行操作,在调用doFilter方法之前的代码就是放行之前的逻辑,在doFilter之后的代码就是放行之后的逻辑。访问完web资源之后还会回到过滤器,如果有需要可以加入放行之后逻辑 伪代码演示:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截到了请求");
System.out.println("放行前逻辑");
//放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("放行后逻辑");
}
拦截路径@WebFilter(urlPatterns = "/*")
过滤器链:一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。执行顺序如下
拦截器执行顺序:注解配置的Filter,优先级是按照过滤器类名(字符串)的自然顺序。
@Slf4j
@WebFilter("/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//强转Tomcat传入的request实际上是HTTPrequset
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse res = (HttpServletResponse) servletResponse;
//1获取请求url
String url = req.getRequestURI().toString();
log.info("请求的url:{}",url);
//2.判断请求url中是否包含login,如果有,说明是登陆操作,放行
if (url.contains("login")){
log.info("登陆操作,放行");
filterChain.doFilter(servletRequest,servletResponse);
return;
}
//3.获取请求头中的令牌(token)
String jwt = req.getHeader("token");
//4.判断令牌是否存在,如果不存在,返回错误数据 StringUtils.hasLength(jwt) 判断字符串是否有长度
if (!StringUtils.hasLength(jwt)){
log.info("请求头token为空,返回未登录信息");
Result error = Result.error("NOT_LOGIN");
//手动转换 将对象转换成json fastJSON工具包 pom引入依赖
String notLogin = JSONObject.toJSONString(error);
res.getWriter().write(notLogin);
return;
}
//5.解析token,如果解析失败返回错误结果
try {
JwtUtils.parseJWT(jwt);
} catch (Exception e) { //报错说明解析失败 校验不成功
e.printStackTrace();
log.info("校验失败,返回错误信息");
Result error = Result.error("NOT_LOGIN");
String notLogin = JSONObject.toJSONString(error);
res.getWriter().write(notLogin);
}
//6.放行
log.info("令牌合法直接放行");
filterChain.doFilter(servletRequest,servletResponse);
}
}