spring 无法读取 HTTP 消息:org.springframework.http.converter.HttpMessageNotReadableException:缺少所需的请求正文

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35549040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:59:53  来源:igfitidea点击:

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

springinterceptor

提问by Hadi Rasouli

I have and Interceptor and for some reasons i have to read POSTED date included in HttpServletRequestlike this:

我有拦截器,出于某些原因,我必须HttpServletRequest像这样阅读 POSTED 日期:

    InputStream 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("");
    }

after this action i get 400 bad request for ajax Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

执行此操作后,我收到 400 个对 ajax 的错误请求,无法读取 HTTP 消息: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

回答by Hadi Rasouli

Spring provides a class called ContentCachingRequestWrapperwhich extends HttpServletRequestWrapper. This class caches all content read from the getInputStream()and getReader()and allows this content to be retrieved via a getContentAsByteArray(). So we can retrieve InputStreammultiple times for this purpose. This ability provided by method blow in ContentCachingRequestWrapper:

Spring 提供了一个名为ContentCachingRequestWrapperextends的类HttpServletRequestWrapper。此类缓存从getInputStream()和读取的所有内容,getReader()并允许通过getContentAsByteArray(). 因此,我们可以InputStream为此目的多次检索。这种能力由方法吹入提供ContentCachingRequestWrapper

 @Override
   public ServletInputStream getInputStream() throws IOException {
        if (this.inputStream == null) {
            this.inputStream = new ContentCachingInputStream(getRequest().getInputStream());
        }
        return this.inputStream;
    }

This class fix character encoding issues for UTF-8with method below:

此类UTF-8使用以下方法修复字符编码问题:

@Override
public String getCharacterEncoding() {
    String enc = super.getCharacterEncoding();
    return (enc != null ? enc : WebUtils.DEFAULT_CHARACTER_ENCODING);
}

Hereis full detail in ContentCachingRequestWrapper.

这里是完整的细节ContentCachingRequestWrapper

回答by Ali Dehghani

I guess you have a method handler like following:

我猜你有一个像下面这样的方法处理程序:

@RequestMapping(value = "/somewhere", method = POST)
public SomeResponse someHandler(@RequestBody String body, ...) { ... }

And you read the HttpServletRequest's InputStreamin your interceptor. Since you can read the InputStreamonly once, when spring tries to read the InputStreamin order to populate the @RequestBodymethod parameter, it fails and complains with HttpMessageNotReadableException.

并且您在拦截器中读取了HttpServletRequest's InputStream。由于您只能读取InputStream一次,因此当 spring 尝试读取InputStream以填充@RequestBody方法参数时,它会失败并以HttpMessageNotReadableException.

If you seriously need to read the request body multiple times, you should add a filter and decorate the HttpServletRequestin order to add a Multiple Readfeature. For more information you can read this answer.

如果你真的需要多次读取请求体,你应该添加一个过滤器并装饰HttpServletRequest以添加一个Multiple Read特性。有关更多信息,您可以阅读此答案