基于javax.validation結(jié)合spring的最佳實踐
前言
本人先將用到的配置、工具類貼出來,然后一步步告訴大家怎么使用
JSR303 是一套JavaBean參數(shù)校驗的標(biāo)準(zhǔn),它定義了很多常用的校驗注解,我們可以直接將這些注解加在我們JavaBean的屬性上面,就可以在需要校驗的時候進(jìn)行校驗了。
注解如下:

Hibernate validator 在JSR303的基礎(chǔ)上對校驗注解進(jìn)行了擴(kuò)展,擴(kuò)展注解如下:

pom中添加注解
<!--jsr 303-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- hibernate validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.0.Final</version>
</dependency>
Spring配置
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
自己的Violation實體
這里使用的Lombok獲取get和set,使用的@Getter注解
@AllArgsConstructor 這個注解是lombok中為類提供一個全參的構(gòu)造方法
package com.alibaba.xianzhi.validator;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Created by Jackielee on 2017
* @author: lizhilong
* @date: 2017-11-14 18:01:34
*/
@Getter
@AllArgsConstructor
public class Violation implements Serializable {
private static final long serialVersionUID = -1731546219600067986L;
private final String message;
private final Object bean;
private final String property;
private final Object value;
}
封裝一個ViolationBuild
后面會說這個類的用法
package com.alibaba.xianzhi.validator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.collections.CollectionUtils;
/**
* @author: lizhilong
* @date: 2017-11-15 11:41:12
*/
@AllArgsConstructor
public class ViolationBuild{
@Getter
private Set<Violation> violations;
public String getMessage() {
List<String> list = new ArrayList<String>();
for (Violation violation : violations) {
list.add(violation.getMessage());
}
return list.size() > 0 ? list.get(0) : "";
}
public static <T> ViolationBuild build(Set<ConstraintViolation<T>> cvs) {
Set<Violation> result = new HashSet<Violation>();
if (CollectionUtils.isNotEmpty(cvs)) {
for (ConstraintViolation cv : cvs) {
result.add(new Violation(cv.getMessage(), cv.getRootBean() == null ? null : cv.getRootBean().toString(),
cv.getPropertyPath() == null ? null : cv.getPropertyPath().toString(),
cv.getInvalidValue()));
}
}
return new ViolationBuild(result);
}
}
用來校驗實體,構(gòu)建并存儲校驗后的信息ValidatorProvider
package com.alibaba.xianzhi.validator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: lizhilong
* @date: 2017-11-15 11:40:59
*/
@AllArgsConstructor
@Getter
public class ValidatorProvider {
private final Validator validator;
public <T> ViolationBuild validate(T object) {
Set<ConstraintViolation<T>> violations;
try {
violations = validator.validate(object);
} catch (IllegalArgumentException iae) {
throw iae;
} catch (ValidationException ve) {
throw ve;
}
return ViolationBuild.build(violations);
}
public <T> ViolationBuild validate(T object, Class<?>... groups) {
Set<ConstraintViolation<T>> violations;
try {
violations = validator.validate(object, groups);
} catch (IllegalArgumentException iae) {
throw iae;
} catch (ValidationException ve) {
throw ve;
}
return ViolationBuild.build(violations);
}
public <T> ViolationBuild validateProperty(T object, String propertyName, Class<?>... groups) {
Set<ConstraintViolation<T>> violations;
try {
violations = validator.validateProperty(object, propertyName, groups);
} catch (IllegalArgumentException iae) {
throw iae;
} catch (ValidationException ve) {
throw ve;
}
return ViolationBuild.build(violations);
}
public <T> ViolationBuild validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
Set<ConstraintViolation<T>> violations;
try {
violations = validator.validateValue(beanType, propertyName, value, groups);
} catch (IllegalArgumentException iae) {
throw iae;
} catch (ValidationException ve) {
throw ve;
}
return ViolationBuild.build(violations);
}
}
BaseService讓自己的service繼承此類
java不能多繼承 所以如果已經(jīng)繼承了別的類,可以將此類注入出來
此類是為了拿到一個單例的ValidatorProvider
package com.alibaba.xianzhi.base.web;
import javax.annotation.Resource;
import javax.validation.Validator;
import com.alibaba.xianzhi.validator.ValidatorProvider;
/**
* BaseService
* @author: lizhilong
* @date: 2017-11-15 11:41:24
*/
public abstract class BaseService {
@Resource
protected Validator validator;
private ValidatorProvider validatorProvider;
protected ValidatorProvider getValidatorProvider() {
if (validatorProvider == null) {
validatorProvider = new ValidatorProvider(validator);
}
return validatorProvider;
}
}
所需校驗的實體類
說明:Constants為接口常量
@Getter
@AllArgsConstructor
public class SubmitVO extends BaseVO {
@NotNull(message="廠商不能為空")
private Long companyId;
@Length(min=0, max=100, message="標(biāo)題請控制在" + Constants.MAX_TITLE + "個字符以內(nèi)")
@NotNull(message="標(biāo)題不能為空")
private String title;
@Length(min=0, max=65535, message="修復(fù)方案長度不能超過" + Constants.MAX_FIX_ADVICE)
@NotNull(message="修復(fù)方案不能為空")
private String fixAdvice;
}
下面就是如何使用
public BaseResponse save(SubmitVO submitVO ) {
/**
* getValidatorProvider()此方法是BaserService中,
* 上面說到本人的service是繼承此
* service的所以可以直接用
**/
ValidatorProvider validatorProvider = getValidatorProvider();
/**
* validatorProvider調(diào)用validate(Object obj)進(jìn)行校驗
* 返回ViolationBuild
**/
ViolationBuild validateFlaw = validatorProvider.validate(submitVO);
/**
* 此時如果校驗有失敗的 容器中便會存儲信息,ViolationBuild可以通過自己的
* getMessage方法獲取信息(此方法可以自己封裝成自己想要的樣子)
**/
System.out.println(validateFlaw.getMessage());
}
打印結(jié)果:標(biāo)題請控制在100個字符以內(nèi)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java的外部類為什么不能使用private和protected進(jìn)行修飾的講解
今天小編就為大家分享一篇關(guān)于Java的外部類為什么不能使用private和protected進(jìn)行修飾的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04
Java多線程之readwritelock讀寫分離的實現(xiàn)代碼
這篇文章主要介紹了Java多線程之readwritelock讀寫分離的相關(guān)內(nèi)容,文中涉及具體實例代碼,具有一定參考價值,需要的朋友可以了解下。2017-10-10
Springboot打包代碼,反編譯后代碼混淆方式(防止還原代碼)
文章主要介紹了如何對Spring Boot項目進(jìn)行jar包混淆,以防止反編譯還原原始代碼,通過在項目中添加proguard.cfg文件并配置Maven插件,可以實現(xiàn)代碼混淆,從而增加反編譯的難度2024-11-11
Java面試崗常見問題之ArrayList和LinkedList的區(qū)別
ArrayList和LinkedList作為我們Java中最常使用的集合類,很多人在被問到他們的區(qū)別時,憋了半天僅僅冒出一句:一個是數(shù)組一個是鏈表。這樣回答簡直讓面試官吐血。為了讓兄弟們打好基礎(chǔ),我們通過實際的使用測試,好好說一下ArrayList和LinkedList的區(qū)別這道經(jīng)典的面試題2022-01-01
解讀HttpServletRequestWrapper處理request數(shù)據(jù)流多次讀取問題
在Java Web開發(fā)中,獲取HTTP請求參數(shù)是常見需求,本文詳細(xì)討論了通過POST方式獲取參數(shù)的兩種主要方法:使用request.getParameter()適用于application/x-www-form-urlencoded和multipart/form-data內(nèi)容類型;而對于application/json類型的數(shù)據(jù)2024-10-10
java數(shù)據(jù)庫連接池和數(shù)據(jù)庫連接示例
這篇文章主要介紹了java數(shù)據(jù)庫連接池和數(shù)據(jù)庫連接示例,需要的朋友可以參考下2014-05-05

