Spring Boot REST 验证错误响应

Posted

技术标签:

【中文标题】Spring Boot REST 验证错误响应【英文标题】:Spring boot REST validation error response 【发布时间】:2022-02-03 15:03:28 【问题描述】:

控制器方法:

public Mission createMission(final @Valid @RequestBody Mission mission) 

    //save..

    return mission;

我想将所有验证错误信息枚举为json并返回。

我可以通过创建一个新的异常类、在控制器方法参数中添加 BindingResult、在绑定结果有错误时抛出新的异常以及在 @ControllerAdvice 类中处理异常来做到这一点。

if (bindingResult.hasErrors()) 
        throw new InvalidRequestException("Fix input and try again", bindingResult);
    

但我想避免在每个控制器方法中检查 BindingResult,而是全局处理。如果我可以处理异常,我可以做到这一点:org.springframework.web.bind.MethodArgumentNotValidException。但不幸的是Spring boot不允许

@ExceptionHandler(MethodArgumentNotValidException.class)

它显示了模棱两可的异常处理程序,因为处理了相同的异常 ResponseEntityExceptionHandler,并且我无法覆盖 handleException,因为它是最终的。我尝试通过捕获 Exception.class 来覆盖受保护的 ResponseEntity handleMethodArgumentNotValid(),但这根本没有被调用。

有什么方法可以实现这个目标吗?一个简单的任务似乎有很多事情:(

【问题讨论】:

【参考方案1】:

您应该创建一个使用@ControllerAdvice 并扩展ResponseEntityExceptionHandler 的类。然后你可以覆盖方法handleMethodArgumentNotValid。你可以使用类似的东西:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler 

@Override
@ResponseStatus(HttpStatus.BAD_REQUEST)
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) 
    final List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
    Map <String, Set<String>> errorsMap =  fieldErrors.stream().collect(
            Collectors.groupingBy(FieldError::getField,
                    Collectors.mapping(FieldError::getDefaultMessage, Collectors.toSet())
            )
    );
    return new ResponseEntity(errorsMap.isEmpty()? ex:errorsMap, headers, status);
    

【讨论】:

【参考方案2】:

如果您不想扩展到ResponseEntityExceptionHandler,则需要将GlobalExceptionHandler 注释为@ControllerAdvice@ResponseBody

更新: Spring Boot 结合@ControllerAdvice@ResponseBody 创建了一个新的注解@RestControllerAdvice

【讨论】:

【参考方案3】:

我发现了问题,controller的advice放在了common util模块中,Spring好像没有用到,虽然它在组件扫描的同一个base包下。我所做的是在全局抽象类(在公共模块中)中覆盖来自 ResponseEntityExceptionHandler 的方法,然后在其他模块中扩展该类。

【讨论】:

嗨@Shafiul ..我把我的“@controllerAdvice”类放在“com.construction”包中,我的控制器在“com.construction.controller”包上,然后我也无法得到错误当请求中不存在所需参数时 @BhartiLadumor,正如我所提到的,哪个包有控制器建议并不重要。它需要与控制器在同一模块中。您可以通过在全局类中抽象它并在包含控制器的模块中扩展来优化它。希望对你有帮助

以上是关于Spring Boot REST 验证错误响应的主要内容,如果未能解决你的问题,请参考以下文章

响应中未显示 Spring Boot 验证错误消息

如何在 Spring Boot REST API 中启用对 JSON / Jackson @RequestBody 的严格验证?

Spring-Boot REST 服务基本 http 身份验证排除一个端点

错误验证消息格式 Spring boot

Spring boot - 如何在 rest 应用程序中验证 Multipartfile

尝试通过 Spring Boot Rest 使用 Jackson 验证 JSON