Spring validation的Validated注解的使用

  在Controller层有时候需要对接口的输入参数进行校验,若是采用自身的校验逻辑代码来实现的话,会有一些弊端,一是会分散自己的注意力,不能让自己专心撰写业务逻辑代码;二是会让校验逻辑代码和业务逻辑代码产生耦合性,代码体积也比较臃肿。为了规避这种情况,我们可以采用Spring validation的Validated注解来完成接口参数校验的工作,下面举实例说明。

  (1)PositionDO实体类

public class PositionDO {
    @NotEmpty
    private String state;
    @NotEmpty
    private String province;
    @NotEmpty
    private String city;

    public PositionDO() {
    }

    public PositionDO(@NotEmpty String state, @NotEmpty String province, @NotEmpty String city) {
        this.state = state;
        this.province = province;
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "PositionDO{" +
                "state='" + state + '\'' +
                ", province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}

  此处,@NotEmpty采用默认的错误提示,可以通过message方法来提供指定的错误信息。

  (2)PersonProfileDO实体类

public class PersonProfileDO {
    @NotEmpty
    private String id;
    @NotEmpty
    private String sex;
    @NotEmpty
    private String age;
    @NotEmpty
    private String photo;
    @NotNull
    private PositionDO positionDo;

    public PersonProfileDO() {
    }

    public PersonProfileDO(@NotEmpty String id, @NotEmpty String sex, @NotEmpty String age, @NotEmpty String photo, @NotNull PositionDO positionDo) {
        this.id = id;
        this.sex = sex;
        this.age = age;
        this.photo = photo;
        this.positionDo = positionDo;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public PositionDO getPositionDo() {
        return positionDo;
    }

    public void setPositionDo(PositionDO positionDo) {
        this.positionDo = positionDo;
    }

    @Override
    public String toString() {
        return "PersonProfileDO{" +
                "id='" + id + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                ", photo='" + photo + '\'' +
                ", positionDo=" + positionDo +
                '}';
    }
}

  此处,@NotEmpty和@NotNull采用默认的错误提示,可以通过message方法来提供指定的错误信息。

  (3)Controller层接口

@ApiOperation(value="设置个人信息", notes="设置个人详细信息")
@RequestMapping(value = "/setProfileInfo", method = RequestMethod.POST)
public Map<String, Object> setProfileInfo(@Validated @RequestBody @ApiParam(value="个人详细信息", required=true)PersonProfileDO personProfileDo,
                                          BindingResult bindingResult) {
     Map<String, Object> map = new HashMap<>(16);
     if (null != bindingResult && bindingResult.hasErrors()) {
         List<FieldError> fieldErrorsList = bindingResult.getFieldErrors();
         System.out.println("the field error is " + fieldErrorsList);
         map.put("parameterErrors", fieldErrorsList);
     }
     return map;
}

  这里需要注意了,使用@Validated注解的话,必须要结合BindingResult,否则不会起到自动校验的作用;BindingResult的作用是存放@Validated校验不通过的错误信息;此外,BindingResult和@Validated位置必须是邻近的,它们所在的两个参数必须要靠近,中间不能插入第三着,比如下面这样的话,就达不到校验的目的:

setProfileInfo(@Validated @RequestBody @ApiParam(value="个人详细信息", required=true)PersonProfileDO personProfileDo,
         HttpServletRequest httpServletRequest, BindingResult bindingResult)

  在上述的示例接口中,由于@Validated和BindingResult之间插入了HttpServletRequest参数,这样导致@Validated没有起到有效的检验作用。故,@Validate必须和BindingResult绑定使用,并且要遵循就近原则。

  (4)校验效果

  通过swagger来测验,输入参数内容如下,id的值为空:

  接口返回的结果如下:

  上图的红色框就是字段校验失败时的提示信息,目前都是采用默认的消息。

  (5)嵌套校验

  在上述例子中,接口的输入参数PersonProfileDO对象,它若是想对其内部成员PositionDO对象的内部字段进行校验的话,那么在PersonProfileDO类中还需要这样处理positionDo成员,如下图所示:

  必须在字段前面添加@Valid注解,注意了这里不能使用@Validated注解,因为它不支持用于字段。

  (6)嵌套校验的输入参数和校验结果,如下图所示:

输入参数示例:              校验结果:

  到此,Spring的Validation的基本用法已介绍完毕,上述示例可以按部就班地应用到自己的项目中。

posted @ 2020-02-29 15:08  晒太阳的兔子很忙  阅读(18640)  评论(0编辑  收藏  举报