好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

基于javax.validation结合spring的最佳实践

前言

本人先将用到的配置、工具类贴出来,然后一步步告诉大家怎么使用

JSR303 是一套JavaBean参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们JavaBean的属性上面,就可以在需要校验的时候进行校验了。

注解如下:

Hibernate validator 在JSR303的基础上对校验注解进行了扩展,扩展注解如下:

pom中添加注解

?

1

2

3

4

5

6

7

8

9

10

11

12

<!--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配置

?

1

<bean id= "validator" class = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

自己的Violation实体

这里使用的Lombok获取get和set,使用的@Getter注解

@AllArgsConstructor 这个注解是lombok中为类提供一个全参的构造方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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

后面会说这个类的用法

?

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

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测试数据mons.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);

     }

}

用来校验实体,构建并存储校验后的信息ValidatorProvider

?

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

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不能多继承 所以如果已经继承了别的类,可以将此类注入出来

此类是为了拿到一个单例的ValidatorProvider

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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为接口常量

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Getter

@AllArgsConstructor

public class SubmitVO extends BaseVO {

 

     @NotNull (message= "厂商不能为空" )

     private Long companyId;

 

     @Length (min= 0 , max= 100 , message= "标题请控制在" + Constants.MAX_TITLE + "个字符以内" )

     @NotNull (message= "标题不能为空" )

     private String title;

 

     @Length (min= 0 , max= 65535 , message= "修复方案长度不能超过" + Constants.MAX_FIX_ADVICE)

     @NotNull (message= "修复方案不能为空" )

     private String fixAdvice;

}

下面就是如何使用

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public BaseResponse save(SubmitVO submitVO ) {

/**

  * getValidatorProvider()此方法是BaserService中,

  * 上面说到本人的service是继承此 

  * service的所以可以直接用

  **/

ValidatorProvider validatorProvider = getValidatorProvider();

/**

  * validatorProvider调用validate(Object obj)进行校验

  * 返回ViolationBuild

  **/

ViolationBuild validateFlaw = validatorProvider.validate(submitVO);

/**

  * 此时如果校验有失败的 容器中便会存储信息,ViolationBuild可以通过自己的

  * getMessage方法获取信息(此方法可以自己封装成自己想要的样子)

  **/

System.out.println(validateFlaw.getMessage());

  }

打印结果:标题请控制在100个字符以内

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/Icannotdebug/article/details/78541558

查看更多关于基于javax.validation结合spring的最佳实践的详细内容...

  阅读:18次