Springboot集成BeanValidation扩展一:错误提示信息加公共模板
Bean Validator扩展
1、需求
在使用validator时,有个需求就是公用错误提示信息,什么意思?
举个例子:
@NotEmpty非空判断,在资源文件中我不想每个非空判断都写”不能为空“,只需要写”###“,然后提示信息自动会变成”###不能为空“
代码:
public class User{//资源文件中user.name.empty=用户名@NotEmpty(key={user.name.empty})private String name;''' }
//加入name为空,则最终的错误提示为“用户名不能为空”(会自动加上“不能为空”信息)
2、实现方式
有两种实现方式
方式一:手动调用验证方法
注解
@Target({FIELD, ANNOTATION_TYPE}) @Retention(RUNTIME) @ReportAsSingleViolation @Constraint(validatedBy = {}) @NotNull @Size(min = 1) public @interface NotEmpty {String message() default "{key}{com.chyjr.hyb.validator.constraints.empty.message}"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { };String key() default ""; }
验证器
//验证器
public class MyValidator {private static final Logger log = LoggerFactory.getLogger(HybValidator.class);private static Validator validator = null;private static MessageInterpolator msgInterpolator = null;static {if (validator == null) {LocalValidatorFactoryBean factory = (LocalValidatorFactoryBean) ApplicationContextUtil.getBean("validator");validator = factory.getValidator();msgInterpolator = factory.getMessageInterpolator();}} public static HybValidatorResult validate(Object object, Class<?>... groups) {HybValidatorResult result = new HybValidatorResult();Set<ConstraintViolation<Object>> violations = validator.validate(object, groups);Map<String, String> map = new HashMap<>();if (CollectionUtils.isEmpty(violations)) {result.setErrors(false);} else {result.setErrors(true);for (ConstraintViolation<Object> violation : violations) {String path = violation.getPropertyPath().toString();String message = violation.getMessage();if (StringUtils.isBlank(path) || StringUtils.isBlank(message) || map.containsKey(path))continue;message = resolveMessage(message);map.put(path, message);}result.setItems(map);}return result;}private static final Pattern elpattern = Pattern.compile("\\{[^{}]+\\}");private static String resolveMessage(String message) {Matcher matcher = elpattern.matcher(message);try {while (matcher.find()) {String el = matcher.group();//用资源文件信息替换message = {key}{my.empty.message}//注解这里的key会替换成注解NotEmpty定义的key,即//message = {user.name.empty}{my.empty.message}String val = msgInterpolator.interpolate(el, null);if (StringUtils.isBlank(val))continue;message = message.replace(el, val);}} catch (Exception e) {log.error("验证引擎进行数据校验时出现异常, message:{}", message, e);}return message;} }
使用
//调用验证方法获得验证结果
HybValidatorResult bvr = HybValidator.validate(emp, CreateValidator.class);//表示有错误if (bvr.isErrors()) {} //资源文件内容 //my.empty.message=不能为空 //user.name.empty=用户名
方式二:用spring自带的@Validated,无需调用验证方法
这里有个问题:@Validated注解不认注解@NotEmpty中的key,如何解决呢?
最终的实现方案:自定义验证器
代码:
注解
@Documented @Target({FIELD, ANNOTATION_TYPE}) @Retention(RUNTIME) @ReportAsSingleViolation //指定验证器 @Constraint(validatedBy = NotEmptyValidator.class) public @interface NotEmpty {String message() default "{my.empty.message}"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { };String key() default ""; }
验证器:自定义
public class NotEmptyValidator extends AbstractValidator<NotEmpty,Object>{ @Overridepublic void initialize(NotEmpty notEmpty) { } @Overridepublic boolean doIsValid(Object value, ConstraintValidatorContext cc) {return value != null;} } /** * 这里采用模板的设计模式 * @param constraintAnnotation */ public abstract class AbstractValidator<A extends Annotation,T> implements ConstraintValidator<A,T>{ /*** 初始化由具体类实现* @param constraintAnnotation*/@Overridepublic abstract void initialize(A constraintAnnotation); /*** 初始化具体由实现类实现* @param value* @param context* @return*/@Overridepublic boolean isValid(T value, ConstraintValidatorContext context){//获取验证结果,采用模板方法boolean result = doIsValid(value,context);//当验证错误时修改默认信息if(!result){//改变默认提示信息if(ConstraintValidatorContextImpl.class.isAssignableFrom(context.getClass())){ConstraintValidatorContextImpl constraintValidatorContext = (ConstraintValidatorContextImpl)context;//获取默认提示信息String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate();Object key = constraintValidatorContext.getConstraintDescriptor().getAttributes().get("key");//禁用默认提示信息 context.disableDefaultConstraintViolation();//设置提示语(在message前面加上key)context.buildConstraintViolationWithTemplate(key + defaultConstraintMessageTemplate).addConstraintViolation();}} return result;}/*** 真正验证方法* @param value* @param context* @return*/public abstract boolean doIsValid(T value, ConstraintValidatorContext context); }
使用:
调用的时候只要在JavaBean前加上@Validated注解即可
总结:上述就是在工作中遇到的问题,并扩展了Validator
转载于:https://www.cnblogs.com/liruiloveparents/p/9378264.html
Springboot集成BeanValidation扩展一:错误提示信息加公共模板相关推荐
- Springboot集成BeanValidation扩展二:加载jar中的资源文件
一.需求 今天在搭建Springboot框架的时候,又遇到一个需求:在多模块系统中,有些模块想自己管理BeanValidation的资源文件(默认是启动项目claspath下的 ValidationM ...
- springboot集成mybatis源码分析-启动加载mybatis过程(二)
springboot集成mybatis源码分析-启动加载mybatis过程(二) 1.springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解@SpringBootApplicati ...
- py程序可以运行,但打包出的exe运行提示错误:加载“cv2”二进制扩展时检测到递归。请检查OpenCV安装。
py程序里包含有 from pdf2docx import Converter 没有封装之前可以正常运行,但是封装成exe后,运行时闪退.我快速复制下报错的内容. raise ImportError( ...
- springboot集成 security 更改中英文提示信息
如图显示,输入错误密码,提示为英文 springsecurity包下有自带的语言资源包 我们通过自定义messageSource,返回中文的配置文件 //security中文提示信息配置类 @Conf ...
- springboot项目启动时提示错误: 找不到或无法加载主类
问题: springboot项目启动时提示错误: 找不到或无法加载主类 解决方法:
- SpringBoot集成Elasticsearch7.4 实战(一)
在网上已经有好多关于Elasticsearch的介绍,就不在翻来覆去讲一些基本概念,大家感兴趣的可以自己去找一些资料巩固下.这次只为了顾及众多首次接触Elasticsearch,案例都讲的很浅显,还有 ...
- kafka(组件分析 整合springboot集成 实战)
kafka 组件 搭建 springboot集成 实战 kafka 组件 搭建 springboot集成 实战 1.应用场景 1.1 kafka场景 1.2 kafka特性 1.3 消息对比 1.4 ...
- ES入门学习:ElasticSearch、Kibana、ik分词器的安装、简单使用及SpringBoot集成
前言 es是采用Java语言开发,因此,想要安装运行es需要提前准备好jdk环境,关于linux配置jdk在前文linux配置jdk 本文主要介绍es的安装.kibana的安装和简单使用及ik分词器的 ...
- Springboot集成Flyway(适用于多数据源)
1. Flyway 可以将初始化sql在项目启动时候执行,取代单独的DBN更新包 2. 依赖 <dependency><groupId>org.flywaydb</gro ...
最新文章
- 几分钟让小孩的人物涂鸦「动起来」,Meta AI创建了一个奇妙的火柴人世界
- java args例子_Spring AOP中使用args表达式的方法示例
- matlab vector用法,C++ vector 用法汇总
- python定义字符串1hdhdjdjd_python基础总结(字符串)
- 查看用户账户过期信息
- selenium 鼠标悬浮_处理Selenium3+python3定位鼠标悬停才显示的元素
- arm for asterisk1.8
- C++字符串的个人理解
- 十三、JSP9大隐视对象中四个作用域的大小与作用范围
- Leetcode-区域和检索-数组不可变
- Python 爬虫 —— 网页内容解析(lxml)
- python充分理解def语句
- tp5使用RabbitMQ的使用记录
- 【每日一题】打卡 14
- Linux tail命令的使用方法详解
- 【嵌入式软件开发岗位 ---- 面试总结01】
- 音频之WAV格式编码解析
- 谈谈 微软 鲍尔默退休,他错在哪里?该怎么做!
- Springboot 小巧简便的限流器使用 RateLimiter
- 视频大数据存储平台解决方案(ppt)
热门文章
- 老男孩mysql参数配置_MySQL启动相关参数解析
- pymssql mysql_Python利用pymssql访问mysql数据库
- 远程管理口怎么看地址_红烧羊肉怎么样做才能滋味浓郁,咸甜适口,且回味有奶香?看这里...
- android让一个控件跟上面控件对其,学个明白--Android控件架构
- 逆水寒服务器维护7.5,逆水寒7.26日维护到什么时候 逆水寒7.26日游戏改动汇总介绍...
- Linux 命令行上执行多个命令(分隔符简介使用)
- 力扣35. 搜索插入位置
- c# 无法将类型隐式转换_C#中的隐式类型数组
- python程序执行时间_用于在Python中查找程序执行时间的程序
- Java Thread类的静态布尔型interrupted()方法(带示例)