石家庄网站排名优化,wordpress修改布局,企业的网站用vue做的,聊天app开发源码Ioc和Aop是spring的两大重要思想#xff0c;前者指的是控制反转#xff08;Invers of control#xff09;后者指的是面向切面编程#xff08;Aspect oriented programing#xff09;。aop的一大作用就是能将很多重复的功能点抽取出来#xff0c;而用注解或者配置的方式统… Ioc和Aop是spring的两大重要思想前者指的是控制反转Invers of control后者指的是面向切面编程Aspect oriented programing。aop的一大作用就是能将很多重复的功能点抽取出来而用注解或者配置的方式统一给需要此功能的方法进行一个增强 因此aop的一大用途就是用来简化重复而一致的一些功能比如日志打印、登录校验、性能监控、事务管理等。这篇文章讲的是aop在登录校验方面的一种实现 实现步骤 1.编写拦截器实现HandlerIntercepter接口注意HandlerInterceptor是springMVC提供的接口需要引入spring mvc依赖 2.在实现类中重写方法preHandle、postHandle、afterCompletion在方法中实现切面逻辑 3.编写配置类确定使用哪些拦截器拦截器作用于哪些地方多个拦截器之间执行的先后顺序 实现拦截器
编写拦截器重写HandlerInterceptor中的默认方法
package com.dianping.utils;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.dianping.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;import static com.dianping.utils.RedisConstants.LOGIN_USER_KEY;Slf4j
public class RefreshTokenInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate stringRedisTemplate;}Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// TODO 1.获取请求头中的 tokenString token request.getHeader(authorization);if (StrUtil.isBlank(token)) {// 没有 token 无法刷新直接结束return true;}// TODO 2.基于 token 获取 redis 中的用户String tokenKey LOGIN_USER_KEY token;MapObject, Object userMap stringRedisTemplate.opsForHash().entries(tokenKey);// 3.判断用户是否存在if (userMap.isEmpty()) {// redis中没有用户信息无法刷新直接结束return true;}// TODO 5.将查询到的 Hash 数据转为 UserDTO对象UserDTO userDTO BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);// TODO 6.存在保存用户信息到 ThreadLocalUserHolder.saveUser((UserDTO) userDTO);
// log.info(刷新有效期);// TODO 7.刷新 token 有效期stringRedisTemplate.expire(tokenKey,30, TimeUnit.MINUTES);// 8.放行return true;}
}package com.dianping.utils;import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;Slf4j
public class LoginInterceptor implements HandlerInterceptor {/*** Intercept the execution of a handler. Called after HandlerMapping determined* an appropriate handler object, but before HandlerAdapter invokes the handler.* pDispatcherServlet processes a handler in an execution chain, consisting* of any number of interceptors, with the handler itself at the end.* With this method, each interceptor can decide to abort the execution chain,* typically sending an HTTP error or writing a custom response.* pstrongNote:/strong special considerations apply for asynchronous* request processing. For more details see* {link org.springframework.web.servlet.AsyncHandlerInterceptor}.* pThe default implementation returns {code true}.* param request current HTTP request* param response current HTTP response* param handler chosen handler to execute, for type and/or instance evaluation* return {code true} if the execution chain should proceed with the* next interceptor or the handler itself. Else, DispatcherServlet assumes* that this interceptor has already dealt with the response itself.* throws Exception in case of errors* preHandle方法该方法在请求处理之前被调用可以在该方法中进行一些预处理操作*/ Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1.判断是否需要拦截ThreadLocal中是否有用户if (UserHolder.getUser() null) {// 没有需要拦截设置状态码log.info(用户未登录);response.setStatus(401);// 拦截return false;}// 有用户则放行return true;// // 1.获取session
// HttpSession session request.getSession();
// // 2.获取session中的用户
// Object user session.getAttribute(user);
// // 3.判断用户是否存在
// if (user null) {
// // 4.不存在拦截
// response.setStatus(401);
// return false;
// }
// // 5.存在保存到ThreadLocal
// UserHolder.saveUser((UserDTO) user);
// // 6.放行
// return true;}/*** Intercept the execution of a handler. Called after HandlerAdapter actually* invoked the handler, but before the DispatcherServlet renders the view.* Can expose additional model objects to the view via the given ModelAndView.* pDispatcherServlet processes a handler in an execution chain, consisting* of any number of interceptors, with the handler itself at the end.* With this method, each interceptor can post-process an execution,* getting applied in inverse order of the execution chain.* pstrongNote:/strong special considerations apply for asynchronous* request processing. For more details see* {link org.springframework.web.servlet.AsyncHandlerInterceptor}.* pThe default implementation is empty.* param request current HTTP request* param response current HTTP response* param handler the handler (or {link HandlerMethod}) that started asynchronous* execution, for type and/or instance examination* param modelAndView the {code ModelAndView} that the handler returned* (can also be {code null})* throws Exception in case of errors* postHandle方法该方法在请求处理之后、视图渲染之前被调用可以在该方法中对请求处理结果进行一些处理例如修改ModelAndView中的数据、记录日志等。*/Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,Nullable ModelAndView modelAndView) throws Exception {}/*** Callback after completion of request processing, that is, after rendering* the view. Will be called on any outcome of handler execution, thus allows* for proper resource cleanup.* pNote: Will only be called if this interceptors {code preHandle}* method has successfully completed and returned {code true}!* pAs with the {code postHandle} method, the method will be invoked on each* interceptor in the chain in reverse order, so the first interceptor will be* the last to be invoked.* pstrongNote:/strong special considerations apply for asynchronous* request processing. For more details see* {link org.springframework.web.servlet.AsyncHandlerInterceptor}.* pThe default implementation is empty.* param request current HTTP request* param response current HTTP response* param handler the handler (or {link HandlerMethod}) that started asynchronous* execution, for type and/or instance examination* param ex any exception thrown on handler execution, if any; this does not* include exceptions that have been handled through an exception resolver* throws Exception in case of errors*afterCompletion方法该方法在请求处理完成后、视图渲染完成后被调用可以在该方法中进行一些资源清理操作例如释放数据库连接、删除临时文件等。此时无法修改响应结果的内容和格式因为响应已经被发送到客户端了。*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}编写配置类,实现WebMvnConfigurer重写addInterceptor接口
package com.dianping.config;import com.dianping.utils.LoginInterceptor;
import com.dianping.utils.RefreshTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration
public class MvcConfig implements WebMvcConfigurer {AutowiredStringRedisTemplate stringRedisTemplate;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns(/user/code,/user/login).order(1);// order 指定不同拦截器的执行顺序order数字越小的越先执行。// 如果没有用 order 指定执行顺序按照注册的先后顺序执行先注册先执行registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns(/**).order(0);}
}