首先,我大致讲讲是怎么样一个应用场景。
我通过JWT生成用户token,ThreadLocal来保存用户信息。我想在除了登录和注册的时候,获取用户信息。
下面来讲讲如何使用。
拦截器的使用,大致分两步。
1.创建一个类实现HandlerInterceptor,定义拦截内容
2.创建一个类实现WebMvcConfigurer,添加拦截对象和地址
实现后,会有三个方法可以重写,分别是preHandle(调用前执行),postHandle(调用后执行),afterCompletion(完成后执行)。这边我们只使用preHandle和afterCompletion
package com.yjzx.interceptors;
import com.yjzx.pojo.Result;
import com.yjzx.utils.JwtUtil;
import com.yjzx.utils.ThreadLocalUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
//拦截器统一认证
//token
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//令牌验证
String token=request.getHeader("Authorization");
System.out.println(token);
try{
Map<String, Object> claims = JwtUtil.parseToken(token);
//把业务数据存储到ThreadLocal中
ThreadLocalUtil.set(claims);
//放行
return true;
}catch (Exception e){
//http响应状态码为401
response.setStatus(401);
//不放行
return false;
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//清空ThreadLocal中的数据
ThreadLocalUtil.remove();
}
}
注意,要添加@Component注解,表示受Spring容器控制
这边我们重写addInterceptors,其他的挺多的,这边不细说了
添加我们刚创建的拦截器
package com.yjzx.config;
import com.yjzx.interceptors.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//将拦截器注入
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//登录注册不拦截
registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register");
}
}
?
注意,需要添加@Configuration注解
即可使用
当然,实现WebMvcConfigurer是简化的,有兴趣的话可以去下面参考的找一下另外一个
这边我也用了JwtUtil和ThreadLoadUtil,我把代码附上,方便使用
package com.yjzx.utils;
public class ThreadLocalUtil {
//提供ThreadLocal对象
private static final ThreadLocal THREAD_LOCAL=new ThreadLocal();
//根据键获取值
public static <T>T get(){
return (T) THREAD_LOCAL.get();
}
//存储键值对
public static void set(Object value){
THREAD_LOCAL.set(value);
}
//清除ThreadLocal 防止内存泄露
public static void remove(){
THREAD_LOCAL.remove();
}
}
package com.yjzx.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;
import java.util.Map;
public class JwtUtil {
private static final String KEY="yjxz";//final常与static连用,作为类常量使用,一旦赋值不能更改
//接受业务数据
public static String genToken(Map<String,Object> claims){
return JWT.create()
.withClaim("claims",claims)
.withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12))
.sign(Algorithm.HMAC256(KEY));
}
//接受token,验证token,并返回业务数据
public static Map<String,Object> parseToken(String token){
return JWT.require(Algorithm.HMAC256(KEY))
.build()
.verify(token)
.getClaim("claims")
.asMap();
}
}
注:学习内容,如有不足,欢迎补充