我有我自己的ExceptionHandler这是扩大ResponseEntityExceptionHandler
我能捕捉到错误,但请求主体是错误响应创建的时间空
override fun handleHttpMessageNotReadable(e:HttpMessageNotReadableException, headers:HttpHeaders , status:HttpStatus , webRequest: WebRequest):ResponseEntity<Any>{
val rsp = ErrResponse(
Data(
HttpStatus.BAD_REQUEST.name,
e.message!!
),**REQUEST-BODY-NEEDED**[customFilter.payload])
return super.handleExceptionInternal(e, rsp,headers, HttpStatus.BAD_REQUEST, webRequest)
}
所以,我已经使用customRequestfilter得到身体和捕获的身体存在,但顺序precendence为customRequestFilter低只会要求后得到执行。 那么,有没有什么办法可以捕捉请求主体上的错误反应?
CustomRequestFilter
@Component
public class CustomRequestFilter extends OncePerRequestFilter{
public String payload;
public Map<String, Object> reqLog =null;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
int status = HttpStatus.BAD_REQUEST.value();
filterChain.doFilter(wrappedRequest, response);
if (status == response.getStatus()) {
reqLog = getTrace(wrappedRequest, status);
payload = getBody(wrappedRequest, reqLog);/** ITS CAPTURING THE BODY HERE SUCCESSFULLY**/
logTrace(wrappedRequest, reqLog);
}
}
哇,这是非常棘手! 无论如何...
创建自定义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();
完成!
记得清理一下代码,并处理所有可能的例外。