过滤器代码实现
实现逻辑:
A. 获取本次请求的URI
B. 判断本次请求, 是否需要登录, 才可以访问
C. 如果不需要,则直接放行
D. 判断登录状态,如果已登录,则直接放行
E. 如果未登录, 则返回未登录结果
定义登录校验过滤器
自定义一个过滤器 LoginCheckFilter 并实现 Filter 接口, 在doFilter方法中完成校验的逻辑。 那么接下来, 我们就根据上述分析的步骤, 来完成具体的功能代码实现:
package 路径;
import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
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;
// 指定过滤器的 url 匹配模式 ("/*":所有路径都必须匹配过滤器)
//@WebFilter(value = "/*")
@WebFilter(urlPatterns = "/*")
public class CheckLoginFilter implements Filter {
// 路径匹配器
// 用来对比两组路径是否相同
private AntPathMatcher antPathMatcher = new AntPathMatcher();
//定义需要放行的资源
String[] urls = {
"/employee/login",
"/backend/**",
"/front/**",
"/common/**",
"/user/sendMsg",
"/user/login",
"/doc.html",
"/webjars/**",
"/swagger-resources",
"/v2/api-docs"
};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 获取用户访问的路径
String requestURI = request.getRequestURI();
// 判断本次请求的url是否需要放行
boolean flag = checkUri(requestURI);
if (flag) {
// 本次请求的路径是不需要拦截的地址,可以直接放行
// 放行,跳转到下个页面
filterChain.doFilter(request, response);
return;
}
// 检查是否登录了,如果登录了可以直接放行
Object employee = request.getSession().getAttribute("employee");
Object user = request.getSession().getAttribute("user");
if (employee != null || user != null) {
// 放行,跳转到下个页面
filterChain.doFilter(request, response);
return;
}
// 如果没有登录返回错误信息,回到登录页面
// 由于不是controller,需要自己转换json
response.getWriter().print(JSON.toJSONString(R.error("NOTLOGIN")));
}
// 检查本次的请求是否符合放行
private boolean checkUri(String requestURI) {
for (String url : urls) {
// 判断本次请求是否符合放行要求
if (antPathMatcher.match(url, requestURI)) {
return true;
}
}
return false;
}
}
开启组件扫描
package com.itheima.reggie;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@Slf4j
@MapperScan("com.itheima.reggie.mapper")
@ServletComponentScan// Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
@EnableTransactionManagement// 开启对事物管理的支持
@EnableCaching// 开启缓存注解功能
public class MyReggieApp {
public static void main(String[] args) {
SpringApplication.run(MyReggieApp.class,args);
log.info("------项目启动成功-----");
}
}
拦截器代码实现
必须保证页面中有访问controller的操作,否则拦截不了
实现逻辑
A. 获取session中的employee的值
B. 判断employee是否为空,若不为空直接放行
C. 若为空,组织页面上需要的数据,通过response返回,且不放行
D. 配置拦截器需要对那些路径进行拦截和放行
定义登录校验拦截器
package com.itheima.reggie.interceptor;
import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LoginCheckInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取session中的数据
Object employee = request.getSession().getAttribute("employee");
//若为空,不放行,且写回页面指定数据
if (employee == null) {
R r = R.error("NOTLOGIN");
response.getWriter().print(JSON.toJSON(r));
return false;
}
return true;
}
}
对拦截器进行配置
在mvc的配置类(WebMvcConfig)中编写拦截器配置。
@Autowired
LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/employee/login","/backend/**","/front/**");//放行静态资源和登陆资源
}