过滤器的作用是适用于页面的跳转拦截与拦截器的效果一样,这里为大家展示的是过滤器,我是用来拦截登录页面的跳转,意思就是在你没有输入账号和密码登录的时候不能进入登录后的页面进行数据查看。
1、设置LoginCheckFilter类用于编写过滤器implements实现接口Filter,注意要注释这个类,用@WebFilter注释,@WebFilter的作用就是为了让Spring架构的启动类,在项目运行的时候扫描到这个过滤器,如果不添加注释则过滤器不会使用。使用@WebFilter时设置过滤器(filtername=“
loginCheckFilter”,urlPatterns“/*”)其中urlPatterns为过滤器“/*”为过滤所有。
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
}
2、在LoginCheckFilter类里实现Filter接口的dofilter的方法,Servlet过滤器允许你在请求到达目标资源之前或响应发送给客户端之后,对请求和响应进行预处理或后处理。doFilter
方法提供了一个标准的机制来实现这种过滤逻辑。
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
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;
}
3、分析逻辑
1.获得本次请求的URL
String requestURI = request.getRequestURI();
设置一个数组用来存放不需要过滤的uri
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};//不需要处理的请求路径
2.判断本次请求需要处理
boolean check = check(urls,requestURI);
这里的check我把他定义成了一个方法函数,在这里直接调用。方法的意思就是,遍历url数组的所有urls,使用AntPathMatcher来匹配路径,如果路径匹配成功check就返回ture,否则返回false,用check的数值来判断是否要过滤。
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();//路径匹配器,支持通配符
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match=PATH_MATCHER.match(url, requestURI);//匹配路径url
if(match){
return true;
}
}
return false;
}
3.如果不需要处理,则直接放行,当check为ture时
if (check) {
log.info("本次请求{}不需要处理:", requestURI);
filterChain.doFilter(request, response);//直接放行
return;
}
4.判断登录状态,如果已登录,则直接放行,当check为false时
if (request.getSession().getAttribute("employee") != null) {
log.info("用户已登录,id名为:{}", request.getSession().getAttribute("employee"));
filterChain.doFilter(request, response);//直接放行
return;
}
5.如果未登录则返回登录结果,通过输出流方式向客户端页面响应数据
这里的“NOTLOGIN”为前端的js方法,当输出的信息为“NOTLOGIN”时,则跳转到登录页面
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
整体的代码如下:
package com.itheima.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Version:1.0
* @Description: TODO(一句话描述该类的功能)
* @Date: 2024/8/1 下午1:40
* @Author: ACER
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")//urlPatterns是过滤器,过滤所有的方法
@Slf4j
public class LoginCheckFilter implements Filter {
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();//路径匹配器,支持通配符
//过滤的方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.获得本次请求的URL
String requestURI = request.getRequestURI();
log.info("拦截到请求:{}", requestURI);
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};//不需要处理的请求路径
//2.判断本次请求是否需要处理
boolean check = check(urls,requestURI);
//3.如果不需要处理,则直接放行
if (check) {
log.info("本次请求{}不需要处理:", requestURI);
filterChain.doFilter(request, response);//直接放行
return;
}
//4.判断登录状态,如果已登录,则直接放行
if (request.getSession().getAttribute("employee") != null) {
log.info("用户已登录,id名为:{}", request.getSession().getAttribute("employee"));
filterChain.doFilter(request, response);//直接放行
return;
}
log.info("用户未登录");
//5.如果未登录则返回登录结果,通过输出流方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match=PATH_MATCHER.match(url, requestURI);//匹配路径url
if(match){
return true;
}
}
return false;
}
}