一、构建拦截器
1.在controller层创建一个类UserTokenInterceptor
public class UserTokenInterceptor implements HandlerInterceptor {
/**
* 拦截请求,在访问controller调用之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//测试
System.out.println("进入到拦截器,被拦截");
/**
* false :请求被拦截,被驳回,验证出现问题
* true:请求在经过验证校验之后,是ok的,是可以放行的
*/
return false;
}
/**
* 请求访问controller之后,渲染视图之前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 请求访问controller之后,渲染视图之后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.创建WebMvcConfig 类,将UserTokenInterceptor注入到Bean,注册拦截器,添加要拦截的访问路径(/hello)
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public UserTokenInterceptor userTokenInterceptor(){
return new UserTokenInterceptor();
}
/**
* 注册拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userTokenInterceptor())
.addPathPatterns("/hello");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
3.测试。在浏览器里访问路径:http://localhost:8088/hello
4.查看控制台打印的结果,拦截成功。
二、会话判断、错误返回
1.springboot代码中实现会话拦截,错误提示信息返回给前端。
实现思路:将redis里的token和前端传过来的token(request.getHeader("headerUserToken");)进行比较,相等,则不拦截;不相等则拦截;另外处理userId和token为空的情况。拦截时,返回错误信息。
注:
(1)获取header里的headerUserId和headerUserToken是和前端约定好的字段名称。
(2)RedisOperator 类是自己封装的RedisTemplate工具包。
public class UserTokenInterceptor implements HandlerInterceptor {
public static final String REDIS_USER_TOKEN = "redis_user_token";
@Autowired
private RedisOperator redisOperator;
/**
* 拦截请求,在访问controller调用之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//测试
// System.out.println("进入到拦截器,被拦截");
String userId = request.getHeader("headerUserId");
String userToken = request.getHeader("headerUserToken");
if(StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)){
String uniqueToken = redisOperator.get(REDIS_USER_TOKEN + ":" + userId);
if(StringUtils.isBlank(uniqueToken)){
// System.out.println("请登录...");
returnErrorResponse(response, IMOOCJSONResult.errorMsg("请登录..."));
return false;
}else {
if(!uniqueToken.equals(userToken)){
// System.out.println("账号在异地登录...");
returnErrorResponse(response, IMOOCJSONResult.errorMsg("账号在异地登录..."));
return false;
}
}
}else {
System.out.println("请登录...");
returnErrorResponse(response, IMOOCJSONResult.errorMsg("请登录..."));
return false;
}
/**
* false :请求被拦截,被驳回,验证出现问题
* true:请求在经过验证校验之后,是ok的,是可以放行的
*/
return true;
}
public void returnErrorResponse(HttpServletResponse response,
IMOOCJSONResult result){
OutputStream out = null;
try {
response.setContentType("utf-8");
response.setContentType("text/json");
out = response.getOutputStream();
out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.在浏览器里测试
在用户中心,将cookie登录信息清空掉,页面提示错误信息。