一般需要在springmvc中获取请求体中的内容.对请求体中的内容记录或操作后传给下游,springmvc项目中请求体中的内容只能获取一次,在下游无法获取,在下游获取将报如下错误(Required request body is missing: ),需要处理后在下游可获取.
一.环境
- 项目环境
springboot的项目
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.5.RELEASE</version> </dependency>
- 请求数据样例
–data-raw中的部分是请求体RequestBody中的数据内容即POST请求传的json数据部分
curl 'http://localhost:9104/sys/loginAction/login'
-H 'Connection: keep-alive'
-H 'Accept: application/json, text/plain, */*'
-H 'Content-Type: application/json'
-H 'Origin: http://dipc.data-pivot.com:81'
-H 'Referer: http://dipc.data-pivot.com:81/'
-H 'Accept-Language: zh-CN,zh;q=0.9'
--data-raw '{"userCode":"zhangsanl","userPassword":"23","platform":1}' -v
二.POST请求
获取请求内容并操作,一般requestBody中的请求内容消费一次后无法在下游进行二次消费,此时需要在消费后重新设置,即可在Controller中的方法参数@RequestBody
SysUserReqeust userReq中获取到.
- springmvc中的HandlerInterceptor前置拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String clientIp = null;
BufferedReader br = request.getReader();
char[] bys = new char[2048];
int length = 0;
String body = null;
CharArrayWriter caw = null;
try {
caw = new CharArrayWriter();
while ((length = br.read(bys,0,bys.length)) != -1){
caw.write(bys,0,length);
}
body = new String(caw.toCharArray());
} finally {
if(caw != null)
caw.close();
if(br != null)
br.close();
}
if(request instanceof RequestFacade){
// 1.获取RequestFacade中的字段request
Field req = request.getClass().getDeclaredField("request");
req.setAccessible(true);
Request newReq = (Request)req.get(request);
// 2.获取RequestFacade中的字段usingInputStream并设置为false
Field usingInputStream = newReq.getClass().getDeclaredField("usingInputStream");
usingInputStream.setAccessible(true);
usingInputStream.set(newReq,false);
// 3.获取RequestFacade中的字段usingReader并设置为false
Field usingReader = newReq.getClass().getDeclaredField("usingReader");
usingReader.setAccessible(true);
usingReader.set(newReq,false);
// 4.获取RequestFacade中的字段inputStream
Field inputStream = newReq.getClass().getDeclaredField("inputStream");
inputStream.setAccessible(true);
CoyoteInputStream cis = (CoyoteInputStream)inputStream.get(newReq);
// 4-1.获取RequestFacade中的字段inputStream的lib字段
Field ib = cis.getClass().getDeclaredField("ib");
ib.setAccessible(true);
// 4-2.新建InputBuffer并设置ByteBuffer和request(该request是RequestFacade中request字段的coyoteRequest字段值)
InputBuffer inputBuffer = new InputBuffer();
inputBuffer.setByteBuffer(ByteBuffer.wrap(body.getBytes("UTF-8")));
Field coyoteRequest = newReq.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
org.apache.coyote.Request cr = (org.apache.coyote.Request)coyoteRequest.get(newReq);
inputBuffer.setRequest(cr);
// 4-3.设置RequestFacade中的字段inputStream的lib字段为新建inputBuffer
ib.set(cis,inputBuffer);
request.setAttribute("loginBody",body);
SysUserReqeust user = JSON.parseObject(body, SysUserReqeust.class);
clientIp = user.getUserCode();
}
return true;
}
- controller中的相关方法
@PostMapping("login")
public ReturnMsg login(HttpServletRequest request,
@RequestBody
@Validated({ValidateGroup.UsernameAndPwd.class}) SysUserReqeust user,
HttpServletResponse response) throws Exception {
SysUser sysUser = BeanUtil.copyEvalueToT(user, SysUser.class);
ReturnMsg returnMsg = userService.validateUser(user.getPlatform(),sysUser);
return returnMsg;
}
三. 写到最后:
各位看官如果支持博文请点个小爱心支持下博主,博主将在您的支持下继续编写更多的博文进行交流。如有问题也可联系博主进行交流学习,博主QQ:676621871