1. 实现 HandlerInterceptor 接口
package com.xunqi.gulimall.order.interceptor;
import com.xunqi.common.vo.MemberResponseVo;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import static com.xunqi.common.constant.AuthServerConstant.LOGIN_USER;
/**
* @Description: 登录拦截器
* @Created: with IntelliJ IDEA.
* @author: LY
* @createTime: 2020-07-02 18:37
**/
@Component
public class LoginUserInterceptor implements HandlerInterceptor {
//https://www.cnblogs.com/fsmly/p/11020641.html
public static ThreadLocal<MemberResponseVo> loginUser = new ThreadLocal<>();
//在请求到达之前进行拦截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
AntPathMatcher antPathMatcher = new AntPathMatcher();
boolean match = antPathMatcher.match("/order/order/status/**", uri);
boolean match1 = antPathMatcher.match("/payed/notify", uri);
if (match || match1) {
return true;
}
//获取登录的用户信息
MemberResponseVo attribute = (MemberResponseVo) request.getSession().getAttribute(LOGIN_USER);
if (attribute != null) {
//把登录后用户的信息放在ThreadLocal里面进行保存
loginUser.set(attribute);
return true;
} else {
//未登录,返回登录页面
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>alert('请先进行登录,再进行后续操作!');location.href='http://auth.gulimall.com/login.html'</script>");
// session.setAttribute("msg", "请先进行登录");
// response.sendRedirect("http://auth.gulimall.com/login.html");
return false;
}
}
//等待 preHandle 返回true 之后进行调用,且在视图渲染之前被调用
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
//等待 preHandle 返回true 之后进行调用,且在视图渲染之后被调用
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
- preHandle
调用时间:Controller方法处理之前
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行
若返回false,则中断执行,注意:不会进入afterCompletion
- postHandle
调用前提:preHandle返回true
调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒着执行。
备注:postHandle虽然post打头,但post、get方法都能处理
- afterCompletion
调用前提:preHandle返回true
调用时间:DispatcherServlet进行视图的渲染之后
多用于清理资源
2.配置文件中配置拦截器(实现 WebMvcConfigurer )
package com.xunqi.gulimall.order.config;
import com.xunqi.gulimall.order.interceptor.LoginUserInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Description:
* @Created: with IntelliJ IDEA.
* @author: LY
* @createTime: 2020-07-02 18:38
**/
@Configuration
public class OrderWebConfig implements WebMvcConfigurer {
@Autowired
private LoginUserInterceptor loginUserInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截路径
registry.addInterceptor(loginUserInterceptor).addPathPatterns("/**");
}
}
3.业务代码中使用
//获取当前用户登录的信息
MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();