背景:在拦截器中返回格式化json给前端
前提:
网上找了很多例子,都没有靠谱的解决方法,自己总结了这个文章。
1、 Web配置文件中注入拦截器
package com.example.jwtdemo.config;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Web配置文件中注入拦截器
* Spring Boot1.0的时候可以通过继承WebMvcConfigurerAdapter完成,但在Spring Boot2.0
* 中这个适配类是被弃用了的,所以我们可以直接实现WebMvcConfigurer来完成拦截器的添加
*
* @author 任珏朋
* @version V1.0.0 2023/6/2
* @since V100R001
*/
@Component
public class InterceptorConfig implements WebMvcConfigurer {
/**
* 在实现WebMvcConfigurer之后可以选择你要重写的方法,这里重写addInterceptors这个方法来添加自定义的拦截器。
* addInterceptor用于添加你自定义的拦截器实例
* addPathPatterns用于添加要拦截的url,可以写多个。
* excludePathPatterns用于添加不需要拦截的url,可以写多个。
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor()).
excludePathPatterns("/api/user/**") // 直接放行通过的rl
.addPathPatterns("/**"); // 要拦截的url
}
}
2、定义一个拦截器,返回格式化的json给前端
要想返回格式化的json给前端,下面代码中的2个注意点是关键!!!
我这边是写的jwt例子,每次收到前端请求时,都先从请求头中的Authorization字段中取出JWT字符串并进行验证。
代码中DecodedJWT不影响测试,小伙伴们不用关心,本文主要关注返回json如何格式化。
package com.example.jwtdemo.config;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.jwtdemo.jwtUtils.JWTUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* 定义一个拦截器,每次收到前端请求时,都先从请求头中的Authorization字段中取出JWT字符串并进行验证
*
* 自定义拦截器HandlerInterceptor会实现三个方法
*
* preHandle:调用Controller某个方法之前
* postHandle:Controller之后调用,视图渲染之前,如果控制器Controller出现了异常,则不会执行此方法
* afterCompletion:不管有没有异常,这个afterCompletion都会被调用,用于资源清理
*
* @author 任珏朋
* @version V1.0.0 2023/6/2
* @since V100R001
*/
public class JWTInterceptor implements HandlerInterceptor {
/**
* 预处理回调方法,实现处理器预处理
* 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或者处理器
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从http请求头key为Authorization中取出JWT
String JWT = request.getHeader("Authorization");
try {
// 1.校验JWT字符串
DecodedJWT decodedJWT = JWTUtils.decode(JWT);
// 2.如果用到Redis存用户信息的话,那么取出JWT字符串载荷中的随机token,从Redis中获取用户信息
// ...
return true;
}catch (SignatureVerificationException e){
returnJson(response,"无效签名");
e.printStackTrace();
}catch (TokenExpiredException e){
returnJson(response,"token已经过期");
e.printStackTrace();
}catch (AlgorithmMismatchException e){
returnJson(response,"算法不一致");
e.printStackTrace();
}catch (Exception e){
returnJson(response,"token无效");
e.printStackTrace();
}
return false;
}
/**
* 返回格式化后的json到前端页面
*
* @param response
* @param message
* @throws Exception
*/
private void returnJson(HttpServletResponse response, String message) throws Exception{
PrintWriter writer = null;
// 注意点1:这边返回配置为josn格式
response.setContentType("application/json;charset=UTF-8");
try {
Map<String, Object> result = new HashMap<>();
result.put("state", "false");
result.put("msg", message);
writer = response.getWriter();
// 注意点2,这样要用fastjson转换一下后,返回的前端才是格式化后的json格式
writer.print(JSON.toJSONString(result));
} catch (IOException e) {
} finally {
if (writer != null)
writer.close();
}
}
}
3、定义一个controller,用来测试
package com.example.jwtdemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 任珏朋
* @version V1.0.0 2023/5/23
* @since V100R001
*/
@RestController
public class TestController {
/**
* 模拟一个测试接口
*
* @return
*/
@GetMapping("/testF1")
public String test() {
String r = "成功进入方法了";
System.out.println(r);
return r;
}
}