[英]Get request body on @RestControllerAdvise
我正在配置自定义错误处理,以便将每个错误请求记录到我的 API。 在我的场景中,了解请求中传递的有效负载很重要,这样我就可以根据需要修复/测试/重新处理它。
我已经构建了一个简单的@RestControllerAdvise
但我很难从中获取请求正文:
@RestControllerAdvice
class ExceptionHandler {
companion object {
private val logger = getLogger()
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
fun badRequest(e: Exception, request: HttpServletRequest): Exception {
logger.error("Received a bad request with body: ${request.getBodyPlease()}", e) // Note getBodyPlease() is not a real method
return e
}
}
我尝试从请求中读取InputStream
但此时它已经关闭。 另一个问题建议注入RequestContext
并将其设置在Controller
。 这在Bad Request
场景中不起作用,因为它不会执行控制器。 此外,在每个控制器中设置它也没有多大意义。
提前致谢,
编辑
正如@BeUndead 所建议的,我尝试实现一个过滤器来包装请求:
@Component
class RequestWrapperFilter : Filter {
override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
val reqWrapper = ContentCachingRequestWrapper(req as HttpServletRequest)
chain.doFilter(reqWrapper, res)
}
}
然后我试图让身体像request.reader.lines().collect(Collectors.joining())
。 当我尝试过滤器时, ServletRequest
工作正常,我看到了正文。 但是当我尝试使用ContentCachingRequestWrapper
@ExceptionHandler
时,我得到一个空字符串,
正如@BeUndead 所建议的,我实现了一个过滤器来将我的请求包装在ContentCachingRequestWrapper
:
@Component
class RequestWrapperFilter : Filter {
override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
val reqWrapper = ContentCachingRequestWrapper(req as HttpServletRequest)
chain.doFilter(reqWrapper, res)
}
}
然后我可以从contentAsByteArrayProperty
根据需要多次准备身体:
@RestControllerAdvice
class ExceptionHandler {
companion object {
private val logger = getLogger()
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
fun badRequest(e: Exception, request: HttpServletRequest): Exception {
val body = (request as ContentCachingRequestWrapper).contentAsByteArray.toString(Charsets.UTF_8)
logger.error("Received a bad request with body: $body", e)
return e
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.