Customize the response for MethodArgumentNotValidException方法参数无效报错的解决方法,亲测有效,嘿嘿嘿,已解决

方法参数无效异常(MethodArgumentNotValidException)的解决方法

问题分析

在Spring MVC中,当使用@Valid注解对控制器方法的参数进行校验,并且校验失败时,Spring会抛出一个MethodArgumentNotValidException异常。这通常是因为客户端发送的请求数据不符合预期的数据模型定义(例如,字段缺失、类型不匹配、长度限制等)。

报错原因
  • 请求体中的数据与控制器方法参数中定义的数据模型不匹配。
  • 数据模型中定义的校验规则(如@NotNull@Size@Pattern等)未通过。
解决思路
  1. 确保请求数据与数据模型匹配:检查客户端发送的请求数据是否符合后端定义的数据模型。
  2. 定义全局异常处理:通过全局异常处理器捕获MethodArgumentNotValidException异常,并返回自定义的响应体。
  3. 自定义校验消息:为数据模型中的校验注解提供自定义的错误消息,以便在响应中返回给客户端。
解决方法
1. 定义数据模型及校验规则

首先,你需要定义一个数据模型类,并使用JSR 303校验注解来定义校验规则。

public class UserDTO {
    @NotNull(message = "ID must not be null")
    private Long id;

    @NotNull(message = "Name must not be null")
    @Size(min = 2, max = 30, message = "Name must be between 2 and 30 characters")
    private String name;

    // getters and setters
}
2. 在控制器方法中使用@Valid注解

在控制器方法中,使用@Valid注解对参数进行校验。
下滑查看解决方法

@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping("/create")
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        // 处理业务逻辑
        return ResponseEntity.ok("User created successfully");
    }
}
3. 定义全局异常处理器

创建一个全局异常处理器来捕获MethodArgumentNotValidException异常,并返回自定义的响应体。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public Map<String, Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, Object> errors = new HashMap<>();
        errors.put("errors", ex.getBindingResult().getFieldErrors());
        // 你可以进一步处理这个map,例如将其转换为更友好的格式
        return errors;
    }
}

注意:上述代码中的ex.getBindingResult().getFieldErrors()会返回一个FieldError对象的列表,每个FieldError对象都包含了字段名、默认消息和拒绝的对象。你可能需要遍历这个列表,并构建一个更适合你需求的响应体。

自定义响应体的示例

如果你希望返回一个更友好的响应体,你可以遍历FieldError列表,并将它们转换为一个更易于理解的格式。

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Map<String, Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
    Map<String, Object> errors = new HashMap<>();
    ex.getBindingResult().getFieldErrors().forEach(fieldError -> {
        String fieldName = fieldError.getField();
        String errorMessage = fieldError.getDefaultMessage();
        errors.put(fieldName, errorMessage);
    });
    return Map.of("status", "error", "message", "Validation failed", "errors", errors);
}

这样,当校验失败时,客户端将收到一个包含字段名和对应错误消息的响应体。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值