Ого, это было сложно!В любом случае ...
Создайте свой пользовательский HttpInputMessage
, который будет делегироваться к исходному.
class CachedHttpInputMessage implements HttpInputMessage {
private final HttpInputMessage httpInputMessage;
private ByteArrayOutputStream outputStream;
CachedHttpInputMessage(final HttpInputMessage httpInputMessage) {
this.httpInputMessage = httpInputMessage;
}
@Override
public InputStream getBody() throws IOException {
if (outputStream == null) {
outputStream = new ByteArrayOutputStream();
final InputStream body = httpInputMessage.getBody();
final byte[] buffer = new byte[1024];
while (true) {
final int length;
if (!((length = body.read(buffer)) > -1)) {
break;
}
outputStream.write(buffer, 0, length);
}
outputStream.flush();
}
return new ByteArrayInputStream(outputStream.toByteArray());
}
@Override
public HttpHeaders getHeaders() {
return httpInputMessage.getHeaders();
}
}
Создайте свой пользовательский HttpMessageConverter
, расширяя нужный на основе используемых в настоящее времяодин (Jackson
, Gson
и т. д.) и зарегистрируйте его как первый.
class CustomHttpMessageConverter extends MappingJackson2HttpMessageConverter {
@Override
public Object read(
final Type type,
final Class<?> contextClass,
final HttpInputMessage inputMessage) throws IOException {
return super.read(type, contextClass, new CachedHttpInputMessage(inputMessage));
}
@Override
protected Object readInternal(
final Class<?> clazz,
final HttpInputMessage inputMessage) throws IOException {
return super.readInternal(clazz, new CachedHttpInputMessage(inputMessage));
}
}
(в качестве альтернативы вы можете создать универсальную оболочку, как в CachedHttpInputMessage
, и обернуть каждуюнастроен HttpMessageConverter
, просто обновите список, переданный в качестве ввода, до extendMessageConverters
)
@Configuration
class WebConfiguration implements WebMvcConfigurer {
@Override
public void extendMessageConverters(final List<HttpMessageConverter<?>> converters) {
converters.add(0, new CustomHttpMessageConverter());
}
...
}
Выбросьте пользовательский Filter
, а внутри ExceptionHandler
прочитайте тело, используя
final HttpInputMessage inputMessage = e.getHttpInputMessage();
final InputStream body = inputMessage.getBody();
Готово!
Не забудьте немного очистить код и обработать все возможные исключения.