Spring ResponseEntityExceptionHandler and original

2019-09-06 11:56发布

I'm using ResponseEntityExceptionHandler in a Spring Boot-based application, to capture errors in a single place and output a consistent error payload.

Everything works as expected. ResponseEntityExceptionHandler has a method handleHttpMessageNotReadable that can be used to "react" on a client sending an invalid message (in my case a JSON payload).

Again, everything works as expected. If a client POST an invalid JSON document, the code in the handleHttpMessageNotReadable is executed correctly.

Now, for monitoring purposes, I would like to log the invalid JSON. This is the code I'm using inside the handleHttpMessageNotReadable method, to get hold of the payload.

String line = null;
StringBuffer jb = new StringBuffer();
try {
    BufferedReader reader = servletWebRequest.getRequest().getReader();
    while ((line = reader.readLine()) != null)
       jb.append(line);

} catch (IOException e) {
        e.printStackTrace();
}

As expected, I get an exception because the stream has been already consumed by Jackson, for actually parsing the JSON payload:

java.lang.IllegalStateException: getInputStream() has already been called for this request

What would be a simple approach to access the original POST payload? Would it be possible to throw a custom exception which would contain the original payload (MyException extends HttpMessageNotReadableException)?

1条回答
时光不老,我们不散
2楼-- · 2019-09-06 12:40

The request body is converted from JSON into a java type by org.springframework.http.converter.json.MappingJackson2HttpMessageConverter

If erros occur, the HttpMessageNotReadableException is thrown in the super class org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#readJavaType

You can subclass MappingJackson2HttpMessageConverter, overwrite readJavaType(..) and try to throw your own exception or a customized HttpMessageNotReadableException there.

Most likely you will need to clone the input stream, use one to try to deserialize the JSON, and another to use in case you need to throw an exception. This may impact performance, but if thats not a problem, you may give it a try....

查看更多
登录 后发表回答