概念:是一种动态拦截方法的调用机制,类似于过滤器。Spring框架提供的,用来动态拦截控制器方法执行。
作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。
实现HandlerInterceptor接口,并重写其所有的方法。
package com.itheima.tliaswebmanagement.interceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class LoginCheckInterceptor implements HandlerInterceptor { //目标资源方法运行前运行,返回true: 放行, 返回false: 不放行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle ..."); return true; } //目标资源方法运行后运行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle ..."); } //视图渲染完毕后运行,最后运行 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion ..."); } }
注册拦截器,并且添加拦截路径。
package com.itheima.tliaswebmanagement.config; import com.itheima.tliaswebmanagement.interceptor.LoginCheckInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; public class WebConfig implements WebMvcConfigurer { //自动装配方法,将自定义的拦截器通过反射获取 @Autowired private LoginCheckInterceptor checkInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截器和拦截路径 registry.addInterceptor(checkInterceptor).addPathPatterns("/**"); } }
拦截器可以根据需求,配置不同的拦截路径:
步骤如下:
? ? ? ? 1. 获取请求url。
? ? ? ? 2. 判断请求url中是否包含login,如果包含,说明是登录操作,放行。
? ? ? ? 3. 获取请求头中的令牌(token)。
? ? ? ? 4. 判断令牌是否存在,如果不在,返回错误结果(未登录)。
? ? ? ? 5. 解析token,如果解析失败,返回错误结果(未登录)。
? ? ? ? 6. 放行。
流程图如下:
下面是登录校验的核心代码,通过检测用户是否进行登录操作(是:就直接放行),如不是就进行jwt令牌登录校验。
package com.itheima.tliaswebmanagement.interceptor; import com.alibaba.fastjson.JSONObject; import com.itheima.tliaswebmanagement.pojo.Result; import com.itheima.tliaswebmanagement.utils.JwtUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component @Slf4j public class LoginCheckInterceptor implements HandlerInterceptor { //目标资源方法运行前运行,返回true: 放行, 返回false: 不放行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle ..."); String url = request.getRequestURL().toString(); if (url.contains("login")){ log.info("登陆操作, 放行..."); return true; } // 查看请求头中的token令牌 String jwt = request.getHeader("token"); if (!StringUtils.hasLength(jwt)){ Result error = Result.error("NOT_LOGIN"); String notLogin = JSONObject.toJSONString(error); response.getWriter().write(notLogin); return false; } try { // 调用JWT的工具类,进行解析验证 JwtUtils.parseJWT(jwt); } catch (Exception e) { Result error = Result.error("NOT_LOGIN"); String notLogin = JSONObject.toJSONString(error); response.getWriter().write(notLogin); e.printStackTrace(); return false; } // 令牌合法,进行放行 return true; } //目标资源方法运行后运行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle ..."); } //视图渲染完毕后运行,最后运行 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion ..."); } }
在一个项目中会有较多的Controller类,且每一个类都包含数个不同的方法,如果为每一个方法添加try、catch异常处理,整个代码出现臃肿。为了解决这个问题,我们可以订正一个全局异常处理器用来处理所有的异常问题。
在项目中创建一个单独异常处理类,代码如下。
package com.itheima.tliaswebmanagement.exception; import com.itheima.tliaswebmanagement.pojo.Result; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice // 异常类注解 public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) // 定义处理什么种类的注解 public Result ex(Exception exception){ // 异常打印出来 exception.printStackTrace(); return Result.error("出现异常,请联系管理员"); } }
以上就是小编的拦截器Interceptor相关知识点,如果有遗漏之处诚邀诸位指点,也希望各位看官给个点赞、留言加关注,你的支持就是我最大的动力。