基于javax.validation结合spring的最佳实践
前言
本人先将用到的配置、工具类贴出来,然后一步步告诉大家怎么使用
JSR303 是一套JavaBean参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们JavaBean的属性上面,就可以在需要校验的时候进行校验了。
注解如下:
文章图片
Hibernate validator 在JSR303的基础上对校验注解进行了扩展,扩展注解如下:
【基于javax.validation结合spring的最佳实践】
文章图片
pom中添加注解
javax.validation validation-api1.1.0.Final org.hibernate hibernate-validator5.2.0.Final
Spring配置
自己的Violation实体
这里使用的Lombok获取get和set,使用的@Getter注解
@AllArgsConstructor 这个注解是lombok中为类提供一个全参的构造方法
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@AllArgsConstructorpublic 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 */@AllArgsConstructorpublic class ViolationBuild{@Getterprivate Setviolations; public String getMessage() {List list = new ArrayList(); for (Violation violation : violations) {list.add(violation.getMessage()); }return list.size() > 0 ? list.get(0) : ""; }public static ViolationBuild build(Set > cvs) {Set result = new HashSet (); 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
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@Getterpublic class ValidatorProvider {private final Validator validator; publicViolationBuild validate(T object) {Set > violations; try {violations = validator.validate(object); } catch (IllegalArgumentException iae) {throw iae; } catch (ValidationException ve) {throw ve; }return ViolationBuild.build(violations); }public ViolationBuild validate(T object, Class>... groups) {Set > violations; try {violations = validator.validate(object, groups); } catch (IllegalArgumentException iae) {throw iae; } catch (ValidationException ve) {throw ve; }return ViolationBuild.build(violations); }public ViolationBuild validateProperty(T object, String propertyName, Class>... groups) {Set > violations; try {violations = validator.validateProperty(object, propertyName, groups); } catch (IllegalArgumentException iae) {throw iae; } catch (ValidationException ve) {throw ve; }return ViolationBuild.build(violations); }public ViolationBuild validateValue(Class beanType, String propertyName, Object value, Class>... groups) {Set > 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
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 {@Resourceprotected Validator validator; private ValidatorProvider validatorProvider; protected ValidatorProvider getValidatorProvider() {if (validatorProvider == null) {validatorProvider = new ValidatorProvider(validator); }return validatorProvider; }}
所需校验的实体类
说明:Constants为接口常量
@Getter@AllArgsConstructorpublic 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; }
下面就是如何使用
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个字符以内以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 基于爱,才会有“愿望”当“要求”。2017.8.12
- 【38】“劳逸结合”的重要性
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- 韵达基于云原生的业务中台建设 | 实战派
- EasyOA|EasyOA 基于SSM的实现 未完成总结与自我批判
- springboot结合redis实现搜索栏热搜功能及文字过滤
- 基于stm32智能风扇|基于stm32智能风扇_一款基于STM32的智能灭火机器人设计