文章目录
一,登录检测
order模块的所有请求,都需要在登录状态下进行,所以要对所有请求进行拦截,校验登录状态。
cpp
@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;
}
}
这段代码是Spring MVC框架中的HandlerInterceptor
实现的一部分。preHandle
方法在实际的控制器方法执行之前被调用。它的目的是拦截并根据用户是否已登录来控制对某些端点的访问。
下面是逻辑的分解:
-
URI匹配:
- 首先检查传入请求的URI是否与以下两个模式之一匹配:
/order/order/status/**
:这个模式匹配所有以/order/order/status/
开头的URL,包括任何额外的路径元素。/payed/notify
:这是一个精确匹配的路径/payed/notify
。
- 如果URI与这两个模式中的任何一个匹配,则该方法立即返回
true
,允许请求无需进一步检查即可继续。这些路径似乎是配置为绕过登录要求的。
- 首先检查传入请求的URI是否与以下两个模式之一匹配:
-
用户认证检查:
- 接下来尝试从会话中获取登录用户的信息,通过获取名为
LOGIN_USER
的属性。如果用户已经登录,该属性将包含一个表示用户详细信息的MemberResponseVo
对象。 - 如果用户已验证(即
attribute
不为null
),则将用户信息存储在一个名为loginUser
的ThreadLocal
变量中。这使得可以在整个应用程序中方便地访问用户数据,而无需显式传递。 - 之后,该方法返回
true
,允许请求继续到预定的控制器方法。
- 接下来尝试从会话中获取登录用户的信息,通过获取名为
-
处理未认证用户:
- 如果用户未验证(即
attribute
为null
),则向客户端发送HTTP响应,内容类型设置为text/html;charset=UTF-8
。 - 它向响应中写入HTML内容,其中包括JavaScript警告消息以及重定向到登录页面(
http://auth.gulimall.com/login.html
)。这有效地阻止了请求到达预定的端点,并将用户重定向到登录页面。 - 最后,该方法返回
false
,表明请求已被处理且不应进一步继续。
- 如果用户未验证(即
二,HandlerInterceptor的原理和用法
HandlerInterceptor
是 Spring MVC 框架中的一个重要接口,用于在控制器方法执行前后进行拦截操作。通过实现 HandlerInterceptor
接口,开发者可以定义一系列钩子方法来扩展和定制请求处理流程。以下是 HandlerInterceptor
接口的主要原理和用法:
HandlerInterceptor 接口定义
HandlerInterceptor
接口定义了三个方法:
preHandle
: 在控制器方法执行之前被调用。postHandle
: 在控制器方法执行之后,但在视图渲染之前被调用。afterCompletion
: 在整个请求处理完成之后被调用,包括视图渲染。
方法签名
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
方法用途
-
preHandle
:- 这个方法在控制器方法执行前被调用。
- 如果返回
true
,则请求将继续;如果返回false
,则请求将不再继续,并且不会调用控制器方法。 - 常用于权限验证、记录日志等操作。
-
postHandle
:- 这个方法在控制器方法执行后、视图渲染之前被调用。
- 可以用来修改模型数据或做一些清理工作。
- 例如,修改视图名称或添加模型数据。
-
afterCompletion
:- 这个方法在整个请求完成后被调用。
- 可以用来释放资源或记录异常。
- 通常用于关闭数据库连接或其他需要在请求结束后执行的操作。
使用示例
下面是一个简单的使用示例:
java
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 检查用户是否登录
MemberResponseVo member = (MemberResponseVo) request.getSession().getAttribute("LOGIN_USER");
if (member != null) {
// 用户已登录,可以继续
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>");
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 该方法在控制器方法执行后、视图渲染之前调用
// 可以在这里做数据清理等工作
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 该方法在整个请求完成后调用
// 可以用来释放资源或记录异常
}
}
注册拦截器
要让拦截器生效,需要将其注册到 Spring MVC 的配置中。可以通过以下方式之一进行注册:
-
使用 XML 配置:
xml<mvc:interceptors> <bean class="com.example.MyHandlerInterceptor"/> </mvc:interceptors>
-
使用 Java 配置:
java@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyHandlerInterceptor()); } }
总结
HandlerInterceptor
提供了一个强大的机制来扩展 Spring MVC 应用程序的功能。通过实现这些方法,你可以轻松地添加诸如身份验证、日志记录、性能监控等功能,而无需修改现有的控制器代码。