实现步骤:
一、自定义一个拦截器配置类,里面可以配置不同的拦截器,比如校验token的、校验权限的等,在里面可以设置拦截的路径和放行的路径等。
二、自定义注解(以校验token为例子,我自定义了@NotCheckToken
这个注解,当控制层使用这个注解,表示放行,该接口不进行token的校验)
三、实现具体的拦截器,比如token校验的,你校验token的逻辑要写在这个类里面,具体的处理,preHandler方法表示进行拦截,然后判断是否使用@NotCheckToken
注解, 没有使用这个注解则需要进行token校验。
具体实现
1、InterceptorConfig(拦截器配置类)
package com.lancoo.primaryedu.Interceptor;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @description: 自定义拦截器* @author: daiziru* @date: 2023/7/14 15:39* @param:* @return:**/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {/*** 配置拦截路径** @param registry 拦截器参考*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// token 拦截所有请求,通过判断是否有 @NotCheckToken 注解 决定是否需要校验registry.addInterceptor(tokenInterceptor()) //添加需要的自定义拦截器.addPathPatterns("/**"); //对所有路径进行拦截}/*** token 拦截器注入** @return Token 拦截器*/@Beanpublic TokenInterceptor tokenInterceptor() {return new TokenInterceptor();}}
2、自定义注解NotCheckToken
package com.lancoo.primaryedu.Interceptor;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义 Token 校验注解* @author pky*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotCheckToken {boolean required() default true;
}
3、token具体的拦截器
package com.lancoo.primaryedu.Interceptor;import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.lancoo.common.exception.MyException;
import com.lancoo.common.respone.StatusCode;
import com.lancoo.common.utils.JsonUtil;
import com.lancoo.primaryedu.entity.net.BasePlatOutBean;
import com.lancoo.primaryedu.entity.net.NetUtil;
import com.lancoo.primaryedu.entity.net.OutCome;
import com.lancoo.primaryedu.entity.net.RequestResponse;
import com.lancoo.primaryedu.util.CommonUtil;
import com.lancoo.primaryedu.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;/*** Token 拦截器* @author pky*/
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {@Autowiredprivate TokenUtil tokenUtil;@Autowiredprivate Environment environment;/*** @description: 通过检查是否有@NotCheckToken注解,决定是否进行token校验* @author: daiziru* @date: 2023/7/14 15:31* @param: [request, response, object]* @return: boolean**/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {// 从 http 请求头中取出 tokenString token = CommonUtil.handleHeader(request).getToken();if(null == token || "".equals(token)) {throw new MyException(StatusCode.REMIND, "请求头中不存在token或token不正确!");}// 如果不是映射到方法直接通过if (!(object instanceof HandlerMethod)) {return true;}HandlerMethod handlerMethod = (HandlerMethod) object;Method method = handlerMethod.getMethod();
// 检查用户权限的注解if (method.isAnnotationPresent(NotCheckToken.class)) {NotCheckToken notCheckToken = method.getAnnotation(NotCheckToken.class);if (notCheckToken.required()) {return true;}}return checkToken(request, token);}/*** 校验 token** @param request 请求* @param token 令牌* @return 校验结果,true/通过;false/不通过* @throws Exception 可能出现的异常*/private boolean checkToken(HttpServletRequest request, String token) throws Exception {if (null == token) {token = "";}String ADDR = "/UserMgr/Login/Api/Login.ashx";String yunAddr = environment.getProperty("base.addr");String SysID = environment.getProperty("sys.id");Map<String, String> form = new HashMap<>();form.put("method", "TokenCheck");form.put("token", token);form.put("params", SysID + "|");String result = "";RequestResponse response = NetUtil.postForm(checkBaseUr(yunAddr) + ADDR, form);OutCome<BasePlatOutBean<BasePlatOutBean.BasePlatLoginOutDataBean>> outCome = new OutCome<>();if (response.isSuccessful) {if (!StringUtil.isEmpty(response.Data)) {result = response.Data;}}if (!result.equals("")) {//解析下json字符串Map<String, String> keyValue = new JsonUtil().getKeyValue(result);String re = keyValue.get("result");if (re == null) {return false;}if (re.equals("true")) {return true;}}return false;}public String checkBaseUr(String url) {if (url.endsWith("/")) {return url;}return url + "/";}}