本文介绍: Component// 在controller执行前的逻辑@Override// 在controller执行之前执行的逻辑// 返回 true,将允许请求继续传递到处理程序;//返回 false,将阻止请求传递给处理程序// 在controller执行后、并在视图渲染前执行的逻辑@Override//在服务器响应结束后执行的逻辑@Override@Autowired@Override//registry.addInterceptor() 方法可以向注册表中添加拦截器。
拦截器原理
在 Spring MVC 中,拦截器(Interceptor)是一种机制,用于拦截请求并在处理程序(Controller)执行之前或之后执行一些操作。拦截器允许您在请求的不同阶段(如处理程序执行前、处理程序执行后、视图渲染前、视图渲染后等)添加自定义逻辑。
其中问号就是拦截器处理的范围。
实现自定义拦截器
@Component
public class SampleInterceptor implements HandlerInterceptor {
// 在controller执行前的逻辑
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 在controller执行之前执行的逻辑
System.out.println("Pre-handle logic");
return true; // 返回 true,将允许请求继续传递到处理程序;
//返回 false,将阻止请求传递给处理程序
}
// 在controller执行后、并在视图渲染前执行的逻辑
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("Post-handle logic");
}
//在服务器响应结束后执行的逻辑
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("After-completion logic");
}
}
将自定义拦截器添加到SpringMvc中
@Configuration
public class InterceptorRoll implements WebMvcConfigurer {
@Autowired
LoginTicketInterceptor loginTicketInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//registry.addInterceptor() 方法可以向注册表中添加拦截器。
InterceptorRegistration interceptorRegistration = registry.addInterceptor(loginTicketInterceptor);
//添加拦截器生效路径,以及拦截器忽略的路径
...
}
}
使用拦截器实现权限验证逻辑
关键鉴权逻辑图解:
1.在请求controller之前先经过拦截器,从cookie中获取用户标识,根据用户标识,从redis中取出登录凭证
2.如果登录凭证有效,则设置一个线程与用户信息进行绑定,并将用户信息存入到视图模型中
3.如果凭证无效则跳转到登录页面
4.在用户请求完之后,销毁线程与用户名的绑定
实现:
1.创建工具类ThreadHolder
package com.duhong.util;
import com.duhong.entity.User;
import org.springframework.data.redis.core.StringRedisTemplate;
public class ThreadHolder {
static ThreadLocal<User> users=new ThreadLocal<>();
/**
* 设置线程信息
* @param user
*/
public static void setHolder(User user){
users.set(user);
}
/**
* 获取当前线程的信息
* @return
*/
public static User getHolder(){
return users.get();
}
/**
* 解除线程与当前用户的绑定
*/
public static void remove(){
users.remove();
}
}
2.创建自定义拦截器
@Component
public class LoginTicketInterceptor implements HandlerInterceptor {
@Autowired
StringRedisTemplate redisTemplate;//redis客户端
@Autowired
UserMapper userMapper;//根据用户id查询用户所有信息
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取用户的cookie
Cookie[] cookies = request.getCookies();
String loginOwner=null;
System.out.println("开始鉴权");
for(Cookie cookie:cookies){
if(cookie.getName().equals("loginOwner")){
loginOwner=cookie.getValue();
break;
};
}
LoginTicket ticket=new LoginTicket();
//如果loginOwner不等于null,从redis中获取登录签证
if(loginOwner!=null) {
String s = redisTemplate.opsForValue().get(RedisUtil.getTicket(loginOwner));
ticket = RedisUtil.getObject(s);
//用户已被授权
if (ticket != null && ticket.getStatus() == 1) {
User user = userMapper.selectById(ticket.getUserId());
//将用户信息与当前线程绑定
ThreadHolder.setHolder(user);
return true;
}
}
//如果签证不等于null,而且签证的状态无效则跳转到登录页面
response.sendRedirect("/site/login");
return false;
}
/**
* 在视图层渲染之前将用户信息存入模型
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
if(ThreadHolder.getHolder()!=null&&modelAndView!=null){
//从当前线程中获取用用户信息
modelAndView.addObject("loginUser",ThreadHolder.getHolder());
}
}
/**
* 在服务器响应完本次信息之后,解除当前线程与用户信息的绑定
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
ThreadHolder.remove();
}
}
3.将拦截器加入到SpringMvc中并设置拦截规则
package com.duhong.config;
import com.duhong.filter.LoginTicketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import java.util.List;
@Configuration
public class InterceptorRoll implements WebMvcConfigurer {
@Autowired
LoginTicketInterceptor loginTicketInterceptor;
//配置文件中配置配置需要过滤的路径形式为:路径,路径,...
@Value("${allow.pages}")
String allowPages;
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(loginTicketInterceptor);
interceptorRegistration.addPathPatterns("/**");
String[] split = allowPages.split(",");
for (String allowpage : split) {
System.out.println(allowpage);
//忽略指定页面
interceptorRegistration.excludePathPatterns(allowpage);
}
//忽略静态资源
interceptorRegistration.excludePathPatterns("/css/**","/img/**","/js/**");
}
}
如有收获,就点个赞吧!
原文地址:https://blog.csdn.net/weixin_53333436/article/details/135730227
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_60384.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。