SpringMVC数据绑定校验

在使用springMVC与前端小伙伴对接开发时,最日常的工作莫过于收参、数据绑定、校验等繁琐的工作。springMVC自身提供了较好的支持,这里简单记录,查漏补缺。

1.注解数据绑定

1.1.RequestParam

1
2
3
4
5
@RequestMapping("/get1")
public String get1(@RequestParam(value="p1", required=true, defaultValue = "test")String p1,ModelMap map){
map.put("p1", p1);
return "";
}

required: 是否必须,默认为true,表示请求中一定要有相应的参数,否则将报404错误码
defaultValue: 默认值,表示如果请求中没有同名参数时的默认值,一般分页参数可以这样设计

如果请求参数类似于url?role=admin&role=user,则实际roleList参数入参的数据为“admin,user”,即多个数据之间使用“,”分割;

1
2
3
4
5
6
7
8
9
10
11
12

@RequestMapping("/get1")
public String get1(@RequestParam(value="role") String[] roleList){
return "";
}


@RequestMapping("/get1")
public String get1(@RequestParam(value="list") List<String> list){
return "";
}

1.2.PathVariable

1
2
3
4
@RequestMapping("/get2/detail/{userId}")
public String get2(@PathVariable(value="userId") String userId){
return "";
}

1.3.ModelAttribute

1
2
3
4
@RequestMapping("/get3")
public String get3(@ModelAttribute("user") UserVO user){
return "";
}

只是此处多了一个注解@ModelAttribute("user"),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性

1.4.CookieValue

1
2
3
4
@RequestMapping("/get4")
public String get4(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId){
return "";
}

1.5.RequestHeader

1
2
3
4
@RequestMapping("/get5")
public String get5(@RequestHeader("User-Agent") String userAgent){
return "";
}

2.数据校验

2.1.validator接口验证

  • VO对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class UserVO2 {

    private String name;

    private String password;

    private String email;

    private String phone;

    private Integer age;

    private String desc;


    //getter and setter....

    }
  • 实现Spring的validator接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class UserValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
    return clazz.equals(UserVO2.class);
    }

    @Override
    public void validate(Object target, Errors errors) {
    ValidationUtils.rejectIfEmpty(errors, "name", "name.null","用户名不能为空");
    ValidationUtils.rejectIfEmpty(errors, "password", "password.null", "密码不能为空");
    }

    }
  • 在controller中设置validator验证器,并进行业务校验

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    @InitBinder
    protected void initBinder(WebDataBinder binder){
    binder.setValidator(new UserValidator());
    }


    @ResponseBody
    @RequestMapping (value = "/reg2", produces = "text/html;charset=UTF-8")
    public String doReg2(@Validated UserVO2 user, BindingResult result){
    if(result.hasErrors()){
    String msg = result.getFieldErrors().get(0).getDefaultMessage();
    return msg;
    }
    return "success";
    }

2.2.JSR-303 validation验证

在Spring3.1中增加的了对JSR303 Bean Validation规范的支持,不仅可以对Spring的 MVC进行校验,而且也可以对Hibernate的存储对象进行校验。是一个通用的校验框架。

  • VO对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    public class UserVO {

    @NotBlank(message="用户姓名不能为空")
    @Size (min=3, max=20, message="用户名长度只能在3-20之间")
    private String name;

    @NotBlank(message ="用户密码不能为空")
    @Size (min=6, max=20, message="密码长度只能在6-20之间")
    private String password;

    @Email(message="邮箱格式不正确")
    private String email;

    @Pattern (regexp="^[1][3,4,5,7,8][0-9]{9}$", message="手机格式错误")
    private String phone;

    private Double salary;

    private Integer age;

    private String desc;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getPassword() {
    return password;
    }

    public void setPassword(String password) {
    this.password = password;
    }

    public String getEmail() {
    return email;
    }

    public void setEmail(String email) {
    this.email = email;
    }

    public String getPhone() {
    return phone;
    }

    public void setPhone(String phone) {
    this.phone = phone;
    }

    public Integer getAge() {
    return age;
    }

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

    public String getDesc() {
    return desc;
    }

    public void setDesc(String desc) {
    this.desc = desc;
    }

    @Money(message="标准的金额形式为xxx.xx")
    public Double getSalary() {
    return salary;
    }

    public void setSalary(Double salary) {
    this.salary = salary;
    }
    }
  • 自定义注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Target({ElementType.FIELD,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy=MoneyValidator.class)
    public @interface Money {

    String message() default "不是金额形式";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
    }

  • validator实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class MoneyValidator implements ConstraintValidator<Money, Double> {

    private String moneyReg = "^\\d+(\\.\\d{1,2})?$";//表示金额的正则表达式
    private Pattern moneyPattern = Pattern.compile(moneyReg);

    @Override
    public void initialize(Money money) {

    }

    @Override
    public boolean isValid(Double value, ConstraintValidatorContext context) {
    if (value == null){
    return true;
    }
    return moneyPattern.matcher(value.toString()).matches();
    }

    }
  • 在controller中进行业务校验

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @ResponseBody
    @RequestMapping (value = "/reg", produces = "text/html;charset=UTF-8")
    public String doReg(@Valid UserVO user, BindingResult result){
    if(result.hasErrors()){
    String msg = result.getFieldErrors().get(0).getDefaultMessage();
    return msg;
    }
    return "success";
    }

参考