1.在spring MVC 項目中使用JSR303 校驗資料合法性,一般情況下使用方法為
(1)在接受資料的實體使用注解标添加校驗規則
1 package com.hzsj.wechatdto;
2
3 import org.hibernate.validator.constraints.Length;
4 import org.hibernate.validator.constraints.NotBlank;
5
6 public class MemberApplyDto {
7 @NotBlank(message="注冊号不能為空")
8 @Length(max=6,min=6,message="注冊号必須為6位")
9 private String registerId;
10
11 @NotBlank(message="姓名不能為空")
12 @Length(max=50,message="長度不能超過50個字元")
13 private String name;
14
15 @NotBlank(message="選擇性别")
16 private String gender;
17
18 @NotBlank(message="請填寫身份證号碼")
19 @Length(max = 18,message="身份證号碼不能超過18個字元")
20 private String cardNo;
21
22 @NotBlank(message="請選擇省")
23 private String province;
24
25 @NotBlank(message="請選擇市")
26 private String cityName;
27
28 @NotBlank(message="請選擇縣")
29 private String countyName;
30
31 @NotBlank(message="請填寫詳細位址")
32 @Length(max=50,message="不能超過50個字元")
33 private String detailAddress;
34
35 @NotBlank(message="請選擇婚姻狀況")
36 private String marriage;
37
38 @NotBlank(message="請填寫公司名稱")
39 @Length(max=30,message="公司名稱不能超過30個字元")
40 private String companyName;
41
42 @NotBlank(message="請填寫公司電話")
43 @Length(max=20,message="公司電話不能超過20個字元")
44 private String companyTel;
45
46 @NotBlank(message="請填寫公司位址")
47 @Length(max=50,message="公司位址不能超過50個字元")
48 private String companyAddress;
49
50 @NotBlank(message="請填寫個人履歷")
51 @Length(max=200,message="個人履歷不能超過200字元")
52 private String persomResume;
53
54 @NotBlank(message="請選擇管道平台")
55 private String channelType;
56
57 @NotBlank(message="請填寫保薦人")
58 @Length(max=20,message="保薦人不能超過20個字元")
59 private String recommend;
60
61 @NotBlank(message="uuidCode不能為空")
62 private String uuidCode;
63
64
65 public String getRegisterId() {
66 return registerId;
67 }
68
69 public void setRegisterId(String registerId) {
70 this.registerId = registerId;
71 }
72
73 public String getName() {
74 return name;
75 }
76
77 public void setName(String name) {
78 this.name = name;
79 }
80
81 public String getGender() {
82 return gender;
83 }
84
85 public void setGender(String gender) {
86 this.gender = gender;
87 }
88
89 public String getCardNo() {
90 return cardNo;
91 }
92
93 public void setCardNo(String cardNo) {
94 this.cardNo = cardNo;
95 }
96
97 public String getProvince() {
98 return province;
99 }
100
101 public void setProvince(String province) {
102 this.province = province;
103 }
104
105 public String getCityName() {
106 return cityName;
107 }
108
109 public void setCityName(String cityName) {
110 this.cityName = cityName;
111 }
112
113 public String getCountyName() {
114 return countyName;
115 }
116
117 public void setCountyName(String countyName) {
118 this.countyName = countyName;
119 }
120
121 public String getDetailAddress() {
122 return detailAddress;
123 }
124
125 public void setDetailAddress(String detailAddress) {
126 this.detailAddress = detailAddress;
127 }
128
129 public String getMarriage() {
130 return marriage;
131 }
132
133 public void setMarriage(String marriage) {
134 this.marriage = marriage;
135 }
136
137 public String getCompanyName() {
138 return companyName;
139 }
140
141 public void setCompanyName(String companyName) {
142 this.companyName = companyName;
143 }
144
145 public String getCompanyTel() {
146 return companyTel;
147 }
148
149 public void setCompanyTel(String companyTel) {
150 this.companyTel = companyTel;
151 }
152
153 public String getCompanyAddress() {
154 return companyAddress;
155 }
156
157 public void setCompanyAddress(String companyAddress) {
158 this.companyAddress = companyAddress;
159 }
160
161 public String getPersomResume() {
162 return persomResume;
163 }
164
165 public void setPersomResume(String persomResume) {
166 this.persomResume = persomResume;
167 }
168
169 public String getChannelType() {
170 return channelType;
171 }
172
173 public void setChannelType(String channelType) {
174 this.channelType = channelType;
175 }
176
177 public String getRecommend() {
178 return recommend;
179 }
180
181 public void setRecommend(String recommend) {
182 this.recommend = recommend;
183 }
184
185 public String getUuidCode() {
186 return uuidCode;
187 }
188
189 public void setUuidCode(String uuidCode) {
190 this.uuidCode = uuidCode;
191 }
192
193
194 }
(2)在Controller中使用BindResult 接收校驗的結果
@RequestMapping(value="/apply",method=RequestMethod.POST)
@ResponseBody
public ResultVo memberApply(@Valid MemberApplyDto dto,BindingResult bindingResult,Errors errors){
ResultVo<Object> resultVo = new ResultVo<>();
if(errors.hasErrors()){
List<FieldError> errorsList = bindingResult.getFieldErrors();
Map<String, String> map = new HashMap<>();
for(FieldError fieldError:errorsList){
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
resultVo.setCode(StatusEnums.DATAVALID_ERROR.getCode());
resultVo.setData(map);
resultVo.setMsg(StatusEnums.DATAVALID_ERROR.getMsg());
return resultVo;
}
LoginVo vo = memberApplyService.submitApply(dto);
resultVo.setCode(StatusEnums.SUCCESS.getCode());
resultVo.setMsg(StatusEnums.SUCCESS.getMsg());
resultVo.setData(vo);
return resultVo;
}
2.如果沒有特殊需求的情況下使用上面的校驗即可。但是遇到其他情況上面的校驗就不能滿足或者不能靈活應對了。例如
(1)實體中的字段校驗按照順序進行,如果第一個字段校驗失敗,則接下來的校驗不再進行。
(2)實體的字段校驗按情況分類,分組校驗,再不同方法中校驗的字段和順序不同。
(3)自定義校驗規則。
剛好今天遇到上面的三種情況,接下來用執行個體一一解答。針對上面的需求,JSR303校驗中專門提供了group (驗證規則所屬組)和 @GroupSequence(驗證組的順序) 來實作。
我的需求是表單中的字段按個按順序校驗,如果有前面的字段校驗失敗,則中斷校驗并傳回校驗結果。我的表單中有十幾個字段,我的想法是為每個字段定義一個組,然後按照組的順序進行校驗(如果字段很多會比較麻煩,暫時不知道有什麼更好的辦法, 如果有人知道的話請指教。)于是上面的實體類就變成了下面的樣子
package com.hzsj.wechatdto;
import java.io.Serializable;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import com.hzsj.common.util.annotation.IsUndefined;
public class MemberApplyDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7063091764413674200L;
@NotBlank(message="注冊号不能為空",groups={Default.class})
@Length(max=6,min=6,message="注冊号必須為6位",groups={Default.class})
private String registerId;
@NotBlank(message="請填寫姓名",groups={Validate1.class})
@Length(max=50,message="長度不能超過50個字元",groups={Validate1.class})
private String name;
@NotBlank(message="選擇性别",groups={Validate2.class})
private String gender;
@NotBlank(message="請填寫身份證号碼",groups={Validate3.class})
@Length(max = 18,message="身份證号碼不能超過18個字元",groups={Validate3.class})
private String cardNo;
@NotBlank(message="請選擇戶籍地區",groups={Validate4.class})
@IsUndefined(message="請選擇戶籍地區",groups={Validate4.class})
private String province;
@NotBlank(message="請選擇戶籍地區",groups={Validate5.class})
@IsUndefined(message="請選擇戶籍地區",groups={Validate5.class})
private String cityName;
@NotBlank(message="請選擇戶籍地區",groups={Validate6.class})
@IsUndefined(message="請選擇戶籍地區",groups={Validate6.class})
private String countyName;
@NotBlank(message="請填寫詳細位址",groups={Validate7.class})
@Length(max=50,message="不能超過50個字元",groups={Validate7.class})
private String detailAddress;
@NotBlank(message="請選擇婚姻狀況",groups={Validate8.class})
private String marriage;
@NotBlank(message="請填寫公司名稱",groups={Validate9.class})
@Length(max=30,message="公司名稱不能超過30個字元",groups={Validate9.class})
private String companyName;
@NotBlank(message="請填寫公司電話",groups={Validate10.class})
@Length(max=20,message="公司電話不能超過20個字元",groups={Validate10.class})
private String companyTel;
@NotBlank(message="請填寫公司位址",groups={Validate11.class})
@Length(max=50,message="公司位址不能超過50個字元",groups={Validate11.class})
private String companyAddress;
@NotBlank(message="請填寫個人履曆",groups={Validate12.class})
@Length(max=200,message="個人履曆不能超過200字元",groups={Validate12.class})
private String persomResume;
@NotBlank(message="請選擇管道平台",groups={Validate13.class})
private String channelType;
@NotBlank(message="請填寫保薦人",groups={Validate14.class})
@Length(max=20,message="保薦人不能超過20個字元",groups={Validate14.class})
private String recommend;
@NotBlank(message="uuidCode不能為空",groups={Default.class})
private String uuidCode;
public String getRegisterId() {
return registerId;
}
public void setRegisterId(String registerId) {
this.registerId = registerId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCountyName() {
return countyName;
}
public void setCountyName(String countyName) {
this.countyName = countyName;
}
public String getDetailAddress() {
return detailAddress;
}
public void setDetailAddress(String detailAddress) {
this.detailAddress = detailAddress;
}
public String getMarriage() {
return marriage;
}
public void setMarriage(String marriage) {
this.marriage = marriage;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getCompanyTel() {
return companyTel;
}
public void setCompanyTel(String companyTel) {
this.companyTel = companyTel;
}
public String getCompanyAddress() {
return companyAddress;
}
public void setCompanyAddress(String companyAddress) {
this.companyAddress = companyAddress;
}
public String getPersomResume() {
return persomResume;
}
public void setPersomResume(String persomResume) {
this.persomResume = persomResume;
}
public String getChannelType() {
return channelType;
}
public void setChannelType(String channelType) {
this.channelType = channelType;
}
public String getRecommend() {
return recommend;
}
public void setRecommend(String recommend) {
this.recommend = recommend;
}
public String getUuidCode() {
return uuidCode;
}
public void setUuidCode(String uuidCode) {
this.uuidCode = uuidCode;
}
public interface Validate1{};
public interface Validate2{};
public interface Validate3{};
public interface Validate4{};
public interface Validate5{};
public interface Validate6{};
public interface Validate7{};
public interface Validate8{};
public interface Validate9{};
public interface Validate10{};
public interface Validate11{};
public interface Validate12{};
public interface Validate13{};
public interface Validate14{};
public interface Default{};
}
其中特别說明:實體類中的這些 interface 用來定義一個驗證組,類似一個辨別。然後為每個字段指定相應的驗證組,其餘字段使用預設的驗證組。
接下來聲明一個驗證序列,指定這個序列需要驗證哪些組和驗證的順序。
package com.hzsj.wechatdto;
import javax.validation.GroupSequence;
@GroupSequence(value={MemberApplyDto.Validate1.class,
MemberApplyDto.Validate2.class,
MemberApplyDto.Validate3.class,
MemberApplyDto.Validate4.class,
MemberApplyDto.Validate5.class,
MemberApplyDto.Validate6.class,
MemberApplyDto.Validate7.class,
MemberApplyDto.Validate8.class,
MemberApplyDto.Validate9.class,
MemberApplyDto.Validate10.class,
MemberApplyDto.Validate11.class,
MemberApplyDto.Validate12.class,
MemberApplyDto.Validate13.class,
MemberApplyDto.Validate14.class,
MemberApplyDto.Default.class,
})
public interface ApplySequence {
}
我指定的是驗證所有組,并按照組的順序驗證。如果在某些情況下隻需要驗證其中部分字段的話,可重新定義一個驗證序列,在接下的Controller中去使用這個序列。
@RequestMapping(value="/apply",method=RequestMethod.POST)
@ResponseBody
public ResultVo memberApply(@Validated({ApplySequence.class}) MemberApplyDto dto,BindingResult bindingResult,Errors errors){
ResultVo<Object> resultVo = new ResultVo<>();
if(errors.hasErrors()){
List<FieldError> errorsList = bindingResult.getFieldErrors();
Map<String, String> map = new HashMap<>();
for(FieldError fieldError:errorsList){
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
resultVo.setCode(StatusEnums.DATAVALID_ERROR.getCode());
resultVo.setData(map);
resultVo.setMsg(StatusEnums.DATAVALID_ERROR.getMsg());
return resultVo;
}
LoginVo vo = memberApplyService.submitApply(dto);
resultVo.setCode(StatusEnums.SUCCESS.getCode());
resultVo.setMsg(StatusEnums.SUCCESS.getMsg());
resultVo.setData(vo);
return resultVo;
}
在Controller中需要的注意的是将原來的@Valid 替換成@Validated 。同時指定了我所需要的驗證序列是按照自己定義的驗證序列。
@Valid是javax.validation裡的。
@Validated是@Valid 的一次封裝,是Spring提供的校驗機制使用。
相比@Valid @Validated 提供了幾個新功能
(1)可以通過groups對驗證進行分組
(2)按照序列組來驗證
(3)驗證多個實體
到此基本實作了按照順序按個驗證字段的合法性,但是同時發現了另外的一種情況,前端字段為空的時候會傳過來的undefined,導緻原來的驗證規則失效。所有我們需要自己去定義一個驗證規則去驗證undefined。上面的實體使用的 @IsUndefined 就是我自行定義的。
首先定義一個注解,同時指定實作校驗規則的類 validatedBy = {UndefinedValiadator.class}
package com.hzsj.common.util.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {UndefinedValiadator.class})
public @interface IsUndefined {
//提示資訊
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
其次,實作這個校驗規則
package com.hzsj.common.util.annotation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.util.StringUtils;
public class UndefinedValiadator implements ConstraintValidator<IsUndefined,String>{
@Override
public void initialize(IsUndefined constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtils.isEmpty(value)){
return false;
}
if("undefined".equals(value)){
return false;
}else{
return true;
}
}
}
至此完成了一個自定義的規則,可以在自己的實體類中去使用了
轉載于:https://www.cnblogs.com/li-zhi-long/p/10530321.html