美文网首页Springboot
SpringBoot参数验证(前后端分离设计)

SpringBoot参数验证(前后端分离设计)

作者: 野小火 | 来源:发表于2018-07-24 18:05 被阅读29次

本文的框架使用的是SpringBoot1.5

1.前端表单层

代码中的 @Getter@Setter@ToString 是使用的 lombok 用于替代传统的 settergettertoString方法。

@Getter
@Setter
@ToString
public class UserFormVo {
    /**
     * 用户id,修改用户时是必填项。增加用户时不能传输
     */
    @NotNull(groups = Update.class, message = "用户Id不能为空")
    @Null(groups = Add.class, message = "不能传输用户Id")
    private Long id;

    /**
     * 用户名
     */
    @NotEmpty(groups = Add.class, message = "用户名不能为空")
//    @Null(groups = Update.class, message = "不能修改用户名")
    @Size(min = 5, max = 20, message = "用户名个数必须为5-20位")
    private String name;

    /**
     * 密码。新增用户时不能为空。修改用户时不能修改用户密码
     */
    @NotNull(groups = Add.class, message = "密码不能为空")
    @Null(groups = Update.class, message = "不能修改用户密码")
    private String password;

    /**
     * 用户状态。0禁用,1启用
     */
    @NotNull(group = Add.class, message = "状态不能为空")
    @Range(min = 0, max = 1, message = "状态值不正确")
    private Integer status;

    /**
     * 继承Default类,可以在不指定@Validated的group时,使用所有默认校验方式。
     */
    public interface Add extends Default {
    }

    public interface Update extends Default {
    }
}

2.controller层

校验操作是使用 @Validated 来实现的,通过里面指定的 class 文件来使用不同的注解分组

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 新增用户
     * @Validated 中指定了校验分组,当校验注解中有对应的class时,才会使用对应的校验方式。由于Add.class继承了Default,所以没有指定分组的校验方式也会进行调用
     * controller方法可以再添加一个BindingResult 来接收校验结果,当前后端分离时,因为我们要直接把错误返回前端,所以要直接获取BindingResult中的报错信息。
     * @Return Response是自定义的返回类型。用于同一返回的格式
     */
    @PostMapping("/add")
    public Response addUser(@Validated(UserFormVo.Add.class) @RequestBody UserFormVo formVo) {
        userService.saveUser(formVo);
        return Response.success();
    }

    /**
     * 修改用户
     */
    @PostMapping("/modify")
    public Response updateUser(@Validated(UserFormVo.Update.class) @RequestBody UserFormVo formVo) {
        userService.updateUser(formVo);
        return Response.success();
    }
}

3.GlobalExceptionHandler

当前后端进行分离设计时,不推荐使用BindingResult来接收校验结果,controller的方法中不需要添加BindingResult参数。我改用使用GlobalExceptionHandler来处理错误信息。

controller的方法中指定了@Validated,又没有添加BindingResult参数时,如果参数没有通过校验,就会直接抛出异常,抛出的异常,可以通过使用了@ControllerAdvice的 类进行捕获。

@RestController
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 用于处理参数校验错误
     * @Validated校验失败时会抛出MethodArgumentNotValidException异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Response methodArgumentValidExceptionHandler(MethodArgumentNotValidException e) throws Exception {
        String code = "200001";
        String message = null;
        //如果抛出了异常,这个getErrorCount一定会>0
        if (e.getBindingResult().getErrorCount() > 0) {
            //校验会把所有不通过的选项的错误信息记录下来,现在先默认给前端提供第一个错误信息
            message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        }
        return new Response(code, message);
    }
    
    //...其他捕获全局异常的代码
    
}

相关文章

网友评论

    本文标题:SpringBoot参数验证(前后端分离设计)

    本文链接:https://www.haomeiwen.com/subject/fndgpftx.html