起因:
项目开发时遇到一个问题是对于金额类型的字段,数据库中格式一般为BigDecimal类型,两位小数点,然后在接口定义中如果不定义成String类型的话,就不能使用@pattern注解限定格式,而在hibernate的校验里面,没有相关适合的注解使用来限定金额格式,所以需要自定义一个注解来对这类参数进行校验。如果在接口中传入的参数值小数点后不止两位,在mysql中进行插入的时候会自动进行剪切,如传入1.315元,在入库的时候该参数就可能被剪切成1.35元,最终入库数据为1.35。
解决:自定一个Amount的注解来对金额相关字段进行校验
1 自定义一个声明类
package ****************; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=AmountValidator.class) public @interface Amount { String message() default "{org.validation.constraints.Amount.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2实现校验方式类 @Constraint(validatedBy=AmountValidator.class)中的 AmountValidator类
package *********; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.math.BigDecimal; import java.util.regex.Pattern; public class AmountValidator implements ConstraintValidator<Amount, BigDecimal> { /** * 表示金额的正则表达式 */ private String moneyReg = "^\\d+(\\.\\d{1,2})?$"; private Pattern moneyPattern = Pattern.compile(moneyReg); @Override public void initialize(Amount amount) { } @Override public boolean isValid(BigDecimal value, ConstraintValidatorContext arg1) { return moneyPattern.matcher(value.toString()).matches(); } }
然后在请求实体bean中需要校验的参数上加上 @Amount注解即可使用
3支持国际化(选)
在你的resource文件夹下加上ValidationMessages.properties文件和 ValidationMessages_zh_CN.properties文件
里面自定义错误信息,当浏览器语言被检测为中文时,系统会查找ValidationMessages_zh_CN.properties该文件下的
org.validation.constraints.Amount.message的值,
若无ValidationMessages_zh_CN.properties文件,则会查找默认文件ValidationMessages.properties中
org.validation.constraints.Amount.message的值返回。