一、问题由来

  自己目前在做一个小程序的后台,已经写好了项目中的很多的接口,同时也在进行一些修改,比如添加拦截器,统一校验一个固定的参数是否正确。

在自己添加拦截器之前,这些接口都可以正常访问,可是在添加拦截器之后,再次访问接口就出现异常,异常信息为Required request body is missing

让我有些疑惑,之前还好好的,怎么突然就访问报错了呢?这个错误简直莫名其妙,感觉毫无道理,可是问题却实实在在出现。

二、问题分析

对于出现的这个问题,我首先是把错误信息往百度里面进行搜索,出现各种各样的答案,可是都不是我遇到的问题的答案。当查看各种答案,查看得比较

多的时候,慢慢的理解了出现这个问题的原因。一开始我理解的是,使用注解的方式不对,看了很多篇博文之后才发现问题所在,才搞清楚问题在哪里。

出现这个问题的原因是java后台项目在处理请求时,如果是使用请求对象获取输入流的方式来获取请求参数,只能获取一次请求参数;当第二次获取参数

时就会出现问题,报标题中的错误。至此终于搞清楚问题的原因,request.getInputStream()只能调用一次,我已经在拦截器中调用一次,当再使用注解

@RequestBody的时候,底层也是调用getInputStream()方法,因此抛出异常。

三、解决方案

自己去百度里面查看了很多的答案,也尝试了很多的方案,反反复复的尝试,希望能够解决问题,最终找到一种解决方案。解决方式为给所有的请求都

使用自定义的请求对象,在过滤器中进行处理。在拦截器中同样也是使用自定义的请求对象,这样就可以解决这个问题。原理就是,在自定义的请求对象

中,将获取请求的输入对象流用一个变量保存起来,然后在生成一个新的请求对象即可,代码我已经粘贴在下面:

获取请求参数的方法

/* @Description: 抽取获取请求参数的方法
* @author: dengchao
* @date: 2021/8/18 16:51
* @param: request 请求对象
* @return: String
*/
private String getLoginToken(HttpServletRequest request) throws IOException {
HttpServletRequest requestWrapper = new BodyReaderWrapper(request);

StringBuffer sb = new StringBuffer() ;
InputStream is = requestWrapper.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String s = "" ;
while((s=br.readLine()) != null){
sb.append(s) ;
}
//获取请求参数示例 { "loginToken": "9a1cdf7a143047c8ad5eee87dbdfd24a", "userPhone":"15215426598", "msgType":1}
String str = sb.toString();
JSONObject jsonObject = JSONObject.parseObject(str);
String loginToken = jsonObject.getString("loginToken");
log.info("loginToken--->" + loginToken);
return loginToken;
}

自定义请求类
public class BodyReaderWrapper extends HttpServletRequestWrapper{
//用于将流保存下来
private byte[] requestBody;

public BodyReaderWrapper(HttpServletRequest request) throws IOException {
super(request);
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
}

@Override
public ServletInputStream getInputStream() throws IOException {

final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);

return new ServletInputStream() {

@Override
public int read() throws IOException {
return bais.read();
}

@Override
public boolean isFinished() {
return false;
}

@Override
public boolean isReady() {
return false;
}

@Override
public void setReadListener(ReadListener readListener) {
}
};
}

@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}

使用过滤器来处理所有的请求
@Component
@WebFilter
public class ReplaceStreamFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
BodyReaderWrapper bodyReaderWrapper = new BodyReaderWrapper((HttpServletRequest) request);
chain.doFilter(bodyReaderWrapper, response);
}

@Override
public void destroy() {

}
}

参考文章

https://blog.csdn.net/m0_37542889/article/details/82889617

https://zhuanlan.zhihu.com/p/239948869

https://www.jb51.net/article/193961.htm

Required request body is missing-请求接口报错的更多相关文章

  1. android 请求接口报错 org.apache.http.conn.HttpHostConnectException: Connection to http://192.168.1.90:9090 refused

    No Network Security Config specified, using platform defaultI/System.out: org.apache.http.conn.HttpH ...

  2. 前端传送JSON数据,报Required request body is missing

    声明: 后端为Java,采用SSM框架 前端一个JSON.stringify()传来的json字符串,后端一般用@RequestBody标签来定义一个参数接收 但问题在于,当我使用get方式传JSON ...

  3. [已解决]报错:Required request body is missing

    问题代码: res = requests.post(getXxxxList_url, headers=headers, data={}) 对象网站: angular4 apache 通过验证 (coo ...

  4. @RequestBody对象为空,异常Required request body is missing错误解决

    1.异常 org.springframework.http.converter.HttpMessageNotReadableException: Required request body is mi ...

  5. Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public xxxxxxxx.

    最近在使用 springBoot开发的时候, 使用PostMan访问接口,  返回一个 404 ,  后台报一个 warn : Failed to read HTTP message: org.spr ...

  6. DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

    客户端当发送空的json字符串时,请求RestController时,报错: DefaultHandlerExceptionResolver : Failed to read HTTP message ...

  7. @RequestBody对象为空,异常Required request body is missing

    1.异常 org.springframework.http.converter.HttpMessageNotReadableException: Required request body is mi ...

  8. 关于请求接口报4XX错误,给广大前端同胞进行伸冤澄清,请相信它不一定都是前端的错

    关于请求接口报4XX错误,给广大前端同胞进行伸冤澄清,请相信它不一定都是前端的错 首先确保接口没有写错,参数按照后台要的写,确保自己也没有写错,若页面还是报4xx错误,请站出来大胆的质疑后端,干什么吃 ...

  9. 记一次线上由nginx upstream keepalive与http协议"协作"引起的接口报错率飙高事件

    年前接到个任务,说要解决线上一些手机客户端接口报错率很高的问题.拿到了监控邮件,粗略一看,各种50%+的错误率,简直触目惊心.这种疑难杂症解决起来还是挺好玩的,于是撸起袖子action. 最终的结果虽 ...

随机推荐

  1. SpringMVC的注解关键词解释

    SpringMVC的注解关键词解释 @Controller控制器定义 和Struts1一样,Spring的Controller是Singleton的.这就意味着会被多个请求线程共享.因此,我们将控制器 ...

  2. Hive源码上手及问题解决

    一.编译准备 1.下载源码包 https://github.com/apache/hive/archive/refs/tags/rel/release-2.3.7.zip 或使用git直接拉取 无法解 ...

  3. Codeforces Round #139 (Div. 2) 题解

    vp上古场次ing CF225A Dice Tower 1.题目简述: 有 \(n\) 个骰子被叠在了一起.对于每个骰子上的一个数,与它对面的数的和始终为 \(7\) . 你是小明,你只能从正面看这个 ...

  4. C语言枚举类型

    在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等.以每周七天为例,我 ...

  5. Guava Cache使用的三种姿势

    姿势一 使用expiredAferWriter 优点 简单 粗暴 缺点 同步阻塞问题:如果多个线程同时请求同一个过期的key,只有一个线程能够获得去加载缓存的锁,但是其他未获取加载缓存锁的线程也会阻塞 ...

  6. Leetcode春季打卡活动 第二题:206. 反转链表

    Leetcode春季打卡活动 第二题:206. 反转链表 206. 反转链表 Talk is cheap . Show me the code . /** * Definition for singl ...

  7. 如何在 PyCharm 中设置 Python 代码模板

    #!/usr/bin/env python # -*- coding: utf-8 -*- # Created by iFantastic on $DATE if __name__ == '__mai ...

  8. 在Linux下安装node及npm

    1.解压 # tar Jxf node-v12.18.3-linux-x64.tar.xz 2.移动到指定目录 # mv node-v12.18.3-linux-x64  /usr/local/nod ...

  9. P3209-平面图判定

    平面图 平面图就是所有点的连边不相交的图.(当然是在你尽量想让它不相交的情况下).这一点可以大概理解成拓扑图的性质,即每连一条边就会将某个区域进行分割--很明显,如果两个点分别处在两个不可达的区域,它 ...

  10. 警告: Runner org.junit.internal.runners.ErrorReportingRunner (used on class cn.star.MybatisTest)

    bug描述: 在Springboot整合Junit的时候编写测试类进行测试时, 出现以下错误: 十一月 28, 2019 2:53:48 下午 org.junit.vintage.engine.des ...