教程中使用的是过滤器,但是看了视频之后我就想着都是boot项目了我就用拦截器试试,而且两种方式我都实现了。另外建议各位测试的时候要记得清除缓存同时写了在实现拦截器期间我遇到的一些问题,也请大牛们点评。
第一种:过滤器 具体的内容黑马的视频讲的已经很清楚了,明白过滤器的实现原理还是不难的,今天主要是讲第二种
过滤器的核心代码
@Component
@WebFilter(filterName = "loginCheckFilter",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、获取本次请求的URI
String requestURI = request.getRequestURI();// /backend/index.html
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;
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}
第二种:拦截器
定义springmvc拦截器 实现HandlerInterceptor接口重写方法并添加@component注解来受spring管理
接下来是核心代码
@Component
@Slf4j
public class LoginCheckFilter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info(request.getRequestURI()+"拦截到的请求");
Object employee = request.getSession().getAttribute("employee");
if (employee!=null){
System.out.println("登录了");
return true;
}
else {
System.out.println("没登录");
// String path = request.getContextPath();
// response.sendRedirect("/employee/login");
// response.sendRedirect("https://www.baidu.com");
System.out.println(request.getRequestURI()+"请求的路径是这个");
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return false;
}
}
接下来是创建管理拦截器的类 并实现WebMvcConfigurer接口重写方法 添加@Configuration注解
在addInterceptors方法内部去使用刚才创建的拦截器类loginCheckFilter设置不需要处理即不需要通过拦截器的 因为是boot项目,static包下是默认对静态页面放行(并不是和黑马视频当中的那样额外创建的包,需要设置放行)
@Configuration()
public class SpringMvcSupport implements WebMvcConfigurer {
@Autowired
private LoginCheckFilter loginCheckFilter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckFilter).addPathPatterns("/**")
.excludePathPatterns("/employee/login","/employee/logout","/backend/**","/front/**");
}
}
而后是我在用拦截器遇到的问题
1.我在ssm学习中在创建管理拦截器的类一直都是继承而不是实现 导致我无论访问什么页面idea都显示
后面我是想了下这是boot项目,我记得黑马李老师提了一句还有实现了接口的方式,但是有入侵型,所以老师不建议我们使用,而且老师酱在后面boot整合前后端的时候因为节省时间压根没有用拦截器,所以我一直不了解。后面修改之后运行就没有很大的问题了,注意是没有很大的问题了,所以我接下来要讲第二个我遇到的问题。
2.这个问题不是很影响拦截器的功能,这个问题的出现也许是我学的还是不够扎实。通过分析前端代码
只要后端响应对应的json字符串"NOTLOGIN"就能跳转到登录页面,而我知道我不是很了解前端的代码,再加上这前端页面也不是我自己写所以对代码不是特别熟悉,所以我就想着在拦截器中直接重定向到登录页面不就行了 但是我测试了一下,我进入主页之后发现他执行了else语句但是并没有跳转到登录页面,我以为是我代码写错了于是我跳蛛到百度却依旧行不通,并且控制台的日志是
我不是很理解,于是我被迫用回了响应json数据。不知道这个问题有哪位能够为我这小白解答,第一次写这种类型的文章,会有很多的不规范希望指出。我也是一个小白希望多多点评,相互进步吧