Request Body数据读取

这篇具有很好参考价值的文章主要介绍了Request Body数据读取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

拦截器要读取request body数据的话需要注意一个问题,一旦拦截器把数据流从request读取出来后,后区的接口层就拿不到数据了,因为流是一次性的,那么要解决这个问题,我们就需要在拦截器取出流拿到数据后重新将数据放回流,这样后面的接口层就能正常获取到数据了

下面放出代码实现:

@Component
@Order(10000)
@WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/")
public class HttpServletRequestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig){
 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        String path = "";
        if (servletRequest instanceof HttpServletRequest && servletRequest.getInputStream() != null) {
            path = ((HttpServletRequest) servletRequest).getRequestURI();
            if(path.equals( "/health" )){
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
            //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中
            requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
        }
        //在chain.doFiler方法中传递新的request对象
        if (null == requestWrapper) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            filterChain.doFilter(requestWrapper, servletResponse);
        }
        if(servletResponse.getOutputStream() != null){
            RequestWrapper.transmittableThreadLocal.remove();
        }
    }
 
    @Override
    public void destroy() {
 
    }
}

/**
* <p>Title:HttpServletRequest 包装器</p>
* <p>Description:
 * 解决: request.getInputStream()只能读取一次的问题
 * 目标: 流可重复读
 * </p>
* @author QIQI
* @params
* @return
* @throws
* @date 2020/11/16 14:24
*/
public class RequestWrapper extends HttpServletRequestWrapper {
    public static final ThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();
    /**
     * 请求体
     */
    private String mBody;
 
    public RequestWrapper(HttpServletRequest request) {
        super(request);
        // 将body数据存储起来
        mBody = getBody(request);
        transmittableThreadLocal.set(mBody);
    }
 
    /**
     * 获取请求体
     *
     * @param request 请求
     * @return 请求体
     */
    private String getBody(HttpServletRequest request) {
        return getBodyString(request);
    }
 
    /**
     * 获取请求体
     *
     * @return 请求体
     */
    public String getBody() {
        return mBody;
    }
 
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
 
    @Override
    public ServletInputStream getInputStream() throws IOException {
        // 创建字节数组输入流
        final ByteArrayInputStream bais = new ByteArrayInputStream(mBody.getBytes( StandardCharsets.UTF_8));
 
        return 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 bais.read();
            }
        };
    }
 
    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    private String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}文章来源地址https://www.toymoban.com/news/detail-485655.html

到了这里,关于Request Body数据读取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Required request body is missing 报错解决

    用 PostMan 测试 POST 类型的接口时,出现错误: 直白的翻译就是该传的参数没能传递到后端。我的传参是表单格式: 后端接口的参数接收使用了注解 @RequestBody ,猜想应该是参数格式有问题,把它改成 JSON 格式传递,再次运行就 OK 了。

    2024年02月12日
    浏览(51)
  • postman请求时报错Required request body is missing:

    postman调试端口时后台报错:Required request body is missing: postman这里使用了错误的书写方式 将网页请求参数以json的形式写在Body的raw中

    2024年02月12日
    浏览(60)
  • Elasticsearch Search API之(Request Body Search 查询主体)

    sentence 句子,使用Java的BreakIterator确定的下一个句子边界处的突出显示片段。您可以使用boundary_scanner_locale指定要使用的区域设置。unified highlighter高亮器默认行为。 word 单词,由Java的BreakIterator确定的下一个单词边界处高亮显示的片段。 boundary_scanner_locale 区域设置。该参数采

    2024年04月09日
    浏览(47)
  • kibana重建es索引报错request body is required

    业务需要把mysql的数据同步到es,用es来查。公司用于同步mysql和es的组件,在mysql表新增字段时会对同步的es索引新增字段,但新增的字段类型可能不是我们想要的,因为es不支持索引字段类型的修改和删除,这时就需要重建es索引。这里的重建索引简单说就是新建一个字段正确

    2024年02月16日
    浏览(52)
  • Elasticsearch Search API之(Request Body Search 查询主体)(1)

    “failed”:0 }, “hits”:{ “total”:1, “max_score”:0.2876821, “hits”:[ { “_index”:“map_highlighting_01”, “_type”:“_doc”, “_id”:“erYsbmcBeEynCj5VqVTI”, “_score”:0.2876821, “_source”:{ “context”:“城中西路可以受理外地二代身份证的办理。” }, “highlight”:{ // @1 “context”:[ “城中西

    2024年04月13日
    浏览(49)
  • Required request body is missing: 前端接口报错错误解决

    在前几天的工作中遇到了一个小小的问题 这是完整报错: 这个接口在Apifox上经过测试是没有问题的,那么因此就是前端接口设置出了问题。 解决方法: 这个接口报错的大意是:必需的请求正文缺失 因此检查一下接口文档,发现数据是写在body里的 因此返回检查接口代码,代

    2024年02月15日
    浏览(45)
  • Api接口出现Required request body is missing的解决方法

    在使用PostMan 测试接口的时候,出现如下问题:

    2024年02月15日
    浏览(46)
  • post请求出现required request body is missing错误的问题所在?

    后端接口查询获取数据库中的数据,前端接受数据进行列表展示。 后端接口swagger测试无误,前端报错500:required request body is missing 给出以下两点原因及其方案: 1.后端原因:controller中该接口函数的参数应为请求体@RequestBody,而不是@RequestParam 改为: 2.前端原因:POST与GET请求

    2024年02月04日
    浏览(73)
  • Postman发送post请求时报400错误,Required request body is missing

    项目形参位置存在@RequestBody注解,用Postman发送post请求时报400错误,Required request body is missing。 错误图示: 解决方法: 方法一: 项目中形参位置不使用@RequestBody,在Postman进行Post请求时,在请求路径后直接拼接参数。 方法二: 项目中形参位置使用@RequestBody,在Postman进行Po

    2024年02月11日
    浏览(65)
  • org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

    报错信息 控制台输出的是缺少必须的请求正文 发现从前端 走的请求 携带一个参数 到后端没有接收到 前端代码 后端代码 原因: 报错时:后台代码使用@RequestBody 注解报错i 前端发送请求,没有进这个controller 把@RequestBody 换成 @PathVariable 就好了 注解@RequestBody接收的参数是来自

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包