Spring Validation的3種執行校驗方式

推薦我的另一篇博文:《利用Aspect/Javassist/動態代理/Lombok等方式省略Controller的參數校驗結果處理代碼》。

Validation的註解就不介紹了,大家可以去看源碼包或者網上找相關資料。

這裏直接說執行校驗的3種方式。本文使用的參數註解情況以及請求的參數值如下

/**
 *  用戶類
 * @author z_hh
 * @time 2019年4月21日
 */
@Data
public class User {

	/** id */
	@NotNull(message="id不能爲空")
	private Long id;
	
	/** 姓名 */
	@NotBlank(message="姓名不能爲空")
	private String name;
	
	/** 年齡 */
	@NotNull(message="年齡不能爲空")
	@Max(message="年齡不能超過120歲", value = 120)
	@Min(message="年齡不能小於1歲", value = 1)
	private Integer age;
	
	/** 創建時間 */
	@Future
	private Date createTime;
}

 

{
	"id": 12,
	"name": "",
	"age": 0,
	"createTime": "2018-12-31"
}

第一種:在Controller方法參數前加@Valid註解——校驗不通過時直接拋異常

        /**
	 * 校驗不通過時直接拋異常
	 * @param user
	 * @return
	 */
	@PostMapping("/test1")
	public Object test1(@RequestBody @Valid User user) {
		return "操作成功!";
	}

調用時會拋出一個org.springframework.web.bind.MethodArgumentNotValidException異常:

2019-04-21 11:35:28.600  WARN 10852 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.Object com.example.validation.UserController.test1(com.example.validation.User) with 3 errors: [Field error in object 'user' on field 'createTime': rejected value [Mon Dec 31 08:00:00 CST 2018]; codes [Future.user.createTime,Future.createTime,Future.java.util.Date,Future]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.createTime,createTime]; arguments []; default message [createTime]]; default message [需要是一個將來的時間]] [Field error in object 'user' on field 'age': rejected value [0]; codes [Min.user.age,Min.age,Min.java.lang.Integer,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.age,age]; arguments []; default message [age],1]; default message [年齡不能小於1歲]] [Field error in object 'user' on field 'name': rejected value []; codes [NotBlank.user.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.name,name]; arguments []; default message [name]]; default message [姓名不能爲空]] ]

★使用這種的話一般結合統一異常處理器(或者Aspect、攔截器等)處理。

第二種:在Controller方法參數前加@Valid註解,參數後面定義一個BindingResult類型參數——執行時會將校驗結果放進bindingResult裏面,用戶自行判斷並處理

        /**
	 * 將校驗結果放進BindingResult裏面,用戶自行判斷並處理
	 * @param user
	 * @param bindingResult
	 * @return
	 */
	@PostMapping("/test2")
	public Object test2(@RequestBody @Valid User user, BindingResult bindingResult) {
		// 參數校驗
		if (bindingResult.hasErrors()) {
			String messages = bindingResult.getAllErrors()
				.stream()
				.map(ObjectError::getDefaultMessage)
				.reduce((m1, m2) -> m1 + ";" + m2)
				.orElse("參數輸入有誤!");
			throw new IllegalArgumentException(messages);
		}
		
		return "操作成功!";
	}


第三種:用戶手動調用對應API執行校驗——Validation.buildDefault ValidatorFactory().getValidator().validate(xxx)

        /**
	 * 用戶手動調用對應API執行校驗
	 * @param user
	 * @return
	 */
	@PostMapping("/test3")
	public Object test3(@RequestBody User user) {
		// 參數校驗
		validate(user);
		
		return "操作成功!";
	}

	private void validate(@Valid User user) {
		Set<ConstraintViolation<@Valid User>> validateSet = Validation.buildDefaultValidatorFactory()
				.getValidator()
				.validate(user, new Class[0]);
			if (!CollectionUtils.isEmpty(validateSet)) {
				String messages = validateSet.stream()
					.map(ConstraintViolation::getMessage)
					.reduce((m1, m2) -> m1 + ";" + m2)
					.orElse("參數輸入有誤!");
				throw new IllegalArgumentException(messages);
				
			}
	}

喜歡使用哪一種看你喜歡咯😊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章