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

时间:2016-02-22 08:35:01

标签: spring interceptor

我有和拦截器,由于某些原因,我必须阅读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("");
    }

在这个动作之后我得到了400个关于ajax的错误请求 无法读取HTTP消息:org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

2 个答案:

答案 0 :(得分:6)

Spring提供了一个名为ContentCachingRequestWrapper的类,它扩展了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;
    }

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

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

HereContentCachingRequestWrapper中的完整详细信息。

答案 1 :(得分:2)

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

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

你在拦截器中阅读了HttpServletRequest的{​​{1}}。由于您只能阅读InputStream一次,当spring尝试阅读InputStream以填充InputStream方法参数时,它会失败并向@RequestBody投诉。

如果您真的需要多次阅读请求正文,则应添加过滤器并装饰HttpMessageNotReadableException以添加HttpServletRequest功能。有关详细信息,请参阅此answer