Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法
2023-09-11 14:17:51 时间
1、要被拦截的Controller接口
我们需要一个更新用户信息接口,请求方式为POST,参数类型为对象类型(UserInfo),代码如下:
@Resource
private UserService userService;
/**
* 更新用户信息
*
* @param request
* @param userInfo
* @return
*/
@RequestMapping(value = "/updateUserInfo", produces = "application/json;charset=UTF-8",
method = RequestMethod.POST)
public JSONObject updateUserInfo(HttpServletRequest request, @RequestBody UserInfo userInfo) {
...
userService.updateUserInfo(userInfo);
...
}
2、拦截器
我们要在拦截器中拦截该接口,并获取其请求参数UserInfo对象。
如果只是获取普通的请求对象(eg:用户ID -> userId),我们可以直接在拦截器中,通过如下代码即可获取request请求体中的参数数据:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
......
// user ID为string类型,所以可以直接拿到数据,
// 但是如果参数是对象类型/JSON类型数据,则无法通过这种方式获取!
String userId = request.getParameter("userId");
.....
}
3、HttpServletRequestWrapper解决这一问题
在拦截器中写一个内部类 RequestWrapper ,让其继承 HttpServletRequestWrapper:
class RequestWrapper extends HttpServletRequestWrapper {
RequestWrapper 重写父类方法,最终完整的拦截器代码如下:
/**
* 拦截器:
*
* @author csp
* @date 2022-01-06 15:36:41
*/
public class UserInterceptor implements HandlerInterceptor {
private final static Logger logger = LoggerFactory.getLogger(UserInterceptor.class);
@Resource
private UserService userService;
/**
* 前置拦截
*
* @param request
* @param response
* @param o
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
// 从request请求体中拿到body中的JSON对象参数
RequestWrapper requestWrapper = new RequestWrapper(request);
String jsonBody = requestWrapper.getBody();
UserInfo userInfo = JSONObject.toJavaObject(JSONObject.parseObject(jsonBody), UserInfo.class);
// 根据userInfo校验是否具备权限
Boolean isAuth = userService.getAuthByUserInfo(userInfo);
if (!isAuth) {
// response响应给浏览器无权限,代码略
...
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {}
// RequestWrapper 内部类
class RequestWrapper extends HttpServletRequestWrapper {
private final String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
body = stringBuilder.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
}
这样,就可以在拦截器中,拦截request请求,并获取request请求体中的json/对象类型的参数啦!
相关文章
- 深入java面向对象五:Java的内存管理
- Jmeter里的全能java测试sampler - Java request
- ssh(Spring+Spring mvc+hibernate)——BaseDaoImpl.java
- Java实现 LeetCode 600 不含连续1的非负整数(有些题为了避免使用位运算可以换成动态规划)
- Java实现 LeetCode 409 最长回文串
- Java实现第九届蓝桥杯快速排序
- Java实现汉诺塔问题
- Java实现 蓝桥杯VIP 算法训练 幂方分解
- 【JAVA】Java 异常中e的getMessage()和toString()方法的异同
- [Java Spring JWT] JWT example
- [Java Sprint] Spring Configuration Using Java
- ArcGIS Server 10 for java 注册SOE出现的问题
- Java反射机制在Spring IOC中的应用
- 【JAVA】 02-Java对象细节
- [Java Spring Data] Query by example
- 在SAP ABAP里使用注解@Inject模拟Java Spring
- Atitit.excel导出 功能解决方案 php java C#.net版总集合.doc
- 使用 SAP BTP 创建一个 Spring Boot Java 应用
- Java中switch参数传null会引起异常——Java 语法糖
- Java并发编程实践笔记(一)
- java中介者模式
- java实现服务端开启多线程处理客户端的上传图片请求
- Jsoup一个简短的引论——采用Java抓取网页数据
- Atitit.js javascript异常处理机制与java异常的转换.js exception process Voae
- Java 读写锁 ReentrantReadWriteLock 源码分析
- Java Spring里com.mysql.jdbc.Driver的加载时机
- 【java】Spring Boot启动流程
- 【Java】Spring Boot 教程
- 【面试题系列|Java】spring boot 11问,你能答出几问?