当@Valid body 不满足并且@ExceptionHandler 命中时获取标题

Posted

技术标签:

【中文标题】当@Valid body 不满足并且@ExceptionHandler 命中时获取标题【英文标题】:get headers when @Valid body not satisfy and @ExceptionHandler hits 【发布时间】:2021-10-03 19:51:45 【问题描述】:

我是 springboot 的新手,正在处理一个遗留项目。我已经搜索过,但没有找到答案。

当前工作项目使用@Valid @RequestBody 来验证正文,并使用@ExceptionHandler 来捕获异常。

现在新要求是处理请求标头,无论正文是否有效,我都会使用标头(例如记录)。

问题是我不知道在@ExceptionHandler 命中时如何获取标题。类似的问题是How to get the @RequestBody in an @ExceptionHandler (Spring REST),但我不知道如何从注入的RequestContext 中获取标头(我什至无法解析答案中的getRequestBody() 方法)。

最小的、工作的和可重现的代码被推送到github。


模型:
public class Book 

  @NotBlank(message = "Title is mandatory")
  public String Title;

控制器
@RestController
public class BooksController 

  final Log log = LogFactory.getLog(getClass());

  @PostMapping("/")
  public String add(@RequestHeader("id") String value, @Valid @RequestBody final Book book) 
    log.info(value); // want this value even when hit @ExceptionHandler
    return "added " + book.Title;
  

  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ExceptionHandler(value = MethodArgumentNotValidException.class)
  public String handleInvalidRequest(final MethodArgumentNotValidException e) 
    //log headers; ??
    return e.getMessage();
  


客户
curl -H "id:123" -H "Content-Type: application/json" http://localhost:8080 --data '"Title":""' 
附加信息 jdk 11,springboot 2.5.3,intellij idea 2021。 模型的代码在我无法更改的库中,因此我不知道验证逻辑。

我想应该有很多方法可以解决,比如定义一些自定义的中间件或句柄,但我不熟悉这些,我希望看到代码更改最少的解决方案.谢谢!

【问题讨论】:

【参考方案1】:

@ExceptionalHandler 中,您可以接受HttpServletRequest 来获取标题

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public String handleInvalidRequest(final MethodArgumentNotValidException e, final HttpServletRequest req) 
  //log headers; ??
  req.getHeader("My-Header");
  return e.getMessage();

【讨论】:

以上是关于当@Valid body 不满足并且@ExceptionHandler 命中时获取标题的主要内容,如果未能解决你的问题,请参考以下文章

无效!有装饰器时不运行单元测试

当表单无效时,Angular Validation 呈现 ng-valid

LeetCode 36 Valid Sudoku(合法的数独)

wk_10.md

phpmyadmin EXCEPT SELECT 不可用

python中try Except抛出异常使用方法