gpt4 book ai didi

spring - 如何在@ExceptionHandler(Spring REST)中获取@RequestBody

转载 作者:IT老高 更新时间:2023-10-28 13:47:47 28 4
gpt4 key购买 nike

我正在使用 Spring Boot 1.4.1,其中包括 spring-web-4.3.3。我有一个用 @ControllerAdvice 注释的类和用 @ExceptionHandler 注释的方法来处理服务代码抛出的异常。在处理这些异常时,我想记录作为 PUT 和 POST 操作请求的一部分的 @RequestBody 以便我可以看到导致问题的请求正文,这在我的情况下对于诊断至关重要.

根据 Spring Docs @ExceptionHandler 方法的方法签名可以包括各种内容,包括 HttpServletRequest。请求正文通常可以通过 getInputStream()getReader() 从此处获取,但如果我的 Controller 方法解析请求正文,例如 "@RequestBody Foo fooBody " 正如我所有人所做的那样,在调用我的异常处理程序方法时,HttpServletRequest 的 输入流或阅读器已经关闭。本质上,请求正文已经被 Spring 读取,类似于 here 中描述的问题。 .使用 servlet 的一个常见问题是请求正文只能被读取一次。

不幸的是,@RequestBody 不是异常处理程序方法可用的选项之一,如果是的话,我可以使用它。

我可以将 InputStream 添加到异常处理程序方法中,但这最终与 HttpServletRequest 的 InputStream 相同,因此存在相同的问题。

我还尝试使用 ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest() 获取当前请求,这是获取当前请求的另一个技巧,但这最终是相同的 HttpServletRequest Spring 传递到异常处理程序方法中,因此有同样的问题。

我已经阅读了一些解决方案,例如 thisthis这涉及在过滤器链中插入自定义请求包装器,该包装器将读取请求的内容并缓存它们,以便可以多次读取它们。我不喜欢这个解决方案,因为我不想仅仅为了实现日志记录而中断整个过滤器/请求/响应链(并可能引入性能或稳定性问题),并且如果我有任何大型请求,例如上传的文档(其中我愿意),我不想将其缓存在内存中。此外,如果我只能找到它,Spring 可能已经将 @RequestBody 缓存在某个地方。

顺便说一句,许多解决方案建议使用 ContentCachingRequestWrapper Spring 类,但根据我的经验,这不起作用。除了没有记录之外,查看它的源代码看起来它只缓存参数,而不是请求正文。尝试从此类中获取请求正文总是会导致一个空字符串。

所以我正在寻找我可能错过的任何其他选项。感谢阅读。

最佳答案

接受的答案会创建一个新的 POJO 来传递东西,但是通过重用 http 请求,无需创建其他对象即可实现相同的行为。

Controller 映射示例代码:

public ResponseEntity savePerson(@RequestBody Person person, WebRequest webRequest) {
webRequest.setAttribute("person", person, RequestAttributes.SCOPE_REQUEST);

以及稍后在ExceptionHandler类/方法中可以使用:

@ExceptionHandler(Exception.class)
public ResponseEntity exceptionHandling(WebRequest request,Exception thrown) {

Person person = (Person) request.getAttribute("person", RequestAttributes.SCOPE_REQUEST);

关于spring - 如何在@ExceptionHandler(Spring REST)中获取@RequestBody,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43502332/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com