Hadi Rasouli
Hadi Rasouli

Reputation: 2039

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

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

    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

Upvotes: 3

Views: 40953

Answers (2)

Hadi Rasouli
Hadi Rasouli

Reputation: 2039

Spring provides a class called ContentCachingRequestWrapper which 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 InputStream multiple times for this purpose. This ability provided by method blow in 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-8 with method below:

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

Here is full detail in ContentCachingRequestWrapper .

Upvotes: 6

Ali Dehghani
Ali Dehghani

Reputation: 48133

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 InputStream in your interceptor. Since you can read the InputStream only once, when spring tries to read the InputStream in order to populate the @RequestBody method parameter, it fails and complains with HttpMessageNotReadableException.

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

Upvotes: 4

Related Questions