自定义validation注解解决动态多字段联动校验问题
欢迎大家关注今日头条号「JAVA前线」查看更多精彩分享文章,主要包括源码分析、实际应用、架构思维、职场分享、产品思考1 文章概述
javax.validation是基于JSR-303标准定义的一组接口,目的是使开发者简洁地校验参数,hibernate-validator实现了这一组接口,可以作为工具独立引用。 javax.validation validation-api 1.1.0.Final org.hibernate hibernate-validator 6.0.18.Final
如果是SpringBoot项目则无需显示引用上述依赖,因为SpringBoot已经将上述依赖进行了集成。
2 基本使用2.1 定义模型import java.math.BigDecimal; import java.util.List; import javax.validation.constraints.DecimalMin; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import lombok.Data; @Data public class OrderModelA { @Min(value = 1, message = "订单编号必须大于等于1") @Max(value = 100, message = "订单编号必须小于等于100") private Integer orderId; @NotBlank(message = "订单名称不能为空") private String orderName; @Size(min = 1, max = 10) private List goodsList; @DecimalMin(value = "1", message = "订单金额必须大于等于1") private BigDecimal amount; }
2.2 定义接口import javax.validation.Valid; import javax.validation.constraints.NotNull; import org.springframework.validation.annotation.Validated; import com.java.front.validation.model.OrderModelA; @Validated public interface BizValidateService { void bizMethodA(@Valid OrderModelA model, @NotNull String param); }
2.3 接口实现import javax.validation.Valid; import javax.validation.constraints.NotNull; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; import com.java.front.validation.model.OrderModelA; @Component public class BizValidateServiceImpl implements BizValidateService { @Override public void bizMethodA(@Valid OrderModelA model, @NotNull String param) { System.out.println("execute bizA model=" + JSON.toJSONString(model) + ",param=" + param); } }
2.4 测试用例@RunWith(SpringRunner.class) @SpringBootTest public class TestAuthApplication { @Autowired private BizValidateService bizValidateService; @Test public void testBizValidateA_correct() { OrderModelA model = new OrderModelA(); model.setOrderId(1); model.setOrderName("订单名称"); List goodsList = new ArrayList(); goodsList.add("goods1"); goodsList.add("goods2"); goodsList.add("goods3"); model.setGoodsList(goodsList); model.setAmount(new BigDecimal("10")); bizValidateService.bizMethodA(model, "param"); } @Test public void testBizValidateA_error() { OrderModelA model = new OrderModelA(); model.setOrderId(0); model.setOrderName("订单名称"); List goodsList = new ArrayList(); goodsList.add("goods1"); goodsList.add("goods2"); goodsList.add("goods3"); model.setGoodsList(goodsList); model.setAmount(new BigDecimal("10")); bizValidateService.bizMethodA(model, "param"); } }
2.5 报错信息javax.validation.ConstraintViolationException: bizMethodA.model.orderId: 订单编号必须大于等于1 at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:117) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) at com.java.front.validation.BizValidateServiceImpl$EnhancerBySpringCGLIB$42c25c43.bizMethodA() at com.java.front.TestAuthApplication.testBizValidateA_error(TestAuthApplication.java:62)
3 复杂应用
现在我们假设一种场景订单新增了type1、type2两个字段,这两个字段影响对于orderId值范围判断,也就是说orderId范围判断不再是静态的,而是受其它字段影响。
针对这种情况第一步我们可以构造type1、type2、orderId组合字段,第二步自定义校验器将组合字段拆开进行业务校验。
3.1 定义注解import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD }) @Constraint(validatedBy = TypeAndOrderIdValidator.class) public @interface TypeAndOrderIdValid { String message() default "不满足业务条件"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
3.2 定义校验器import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import com.java.front.validation.model.OrderModelB; public class TypeAndOrderIdValidator implements ConstraintValidator { @Override public boolean isValid(String value, ConstraintValidatorContext context) { String[] array = value.split(OrderModelB.JOINT); int type1 = Integer.parseInt(array[0]); int type2 = Integer.parseInt(array[1]); int orderId = Integer.parseInt(array[2]); if (type1 == 1 && type2 == 2) { return orderId > 20; } return true; } }
3.3 定义模型import java.math.BigDecimal; import java.util.List; import javax.validation.constraints.DecimalMin; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import com.alibaba.fastjson.annotation.JSONField; import com.java.front.server.validation.extend.TypeAndOrderIdValid; import lombok.Data; @Data public class OrderModelB { public static final String JOINT = "_"; @Min(value = 1, message = "订单编号必须大于等于1") @Max(value = 100, message = "订单编号必须小于等于100") private Integer orderId; @NotBlank(message = "订单名称不能为空") private String orderName; @Size(min = 1, max = 10) private List goodsList; @DecimalMin(value = "1", message = "订单金额必须大于等于1") private BigDecimal amount; private int type1; private int type2; @JSONField(serialize = false) private String typeAndOrderIdComposite; @TypeAndOrderIdValid public String getTypeAndOrderIdComposite() { return getType1() + JOINT + getType2() + JOINT + getOrderId(); } }
3.4 定义接口import javax.validation.Valid; import javax.validation.constraints.NotNull; import org.springframework.validation.annotation.Validated; import com.java.front.validation.model.OrderModelB; @Validated public interface BizValidateService { void bizMethodB(@Valid OrderModelB model, @NotNull String param); }
3.5 接口实现import javax.validation.Valid; import javax.validation.constraints.NotNull; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; import com.java.front.server.validation.model.OrderModelB; @Component public class BizValidateServiceImpl implements BizValidateService { @Override public void bizMethodB(@Valid OrderModelB model, @NotNull String param) { System.out.println("execute bizB model=" + JSON.toJSONString(model) + ",param=" + param); } }
3.6 测试用例@RunWith(SpringRunner.class) @SpringBootTest public class TestAuthApplication { @Autowired private BizValidateService bizValidateService; @Test public void testBizValidateB_correct() { OrderModelB model = new OrderModelB(); model.setOrderId(30); model.setOrderName("订单名称"); List goodsList = new ArrayList(); goodsList.add("goods1"); goodsList.add("goods2"); goodsList.add("goods3"); model.setGoodsList(goodsList); model.setAmount(new BigDecimal("10")); model.setType1(1); model.setType2(2); bizValidateService.bizMethodB(model, "param"); } @Test public void testBizValidateB_error() { OrderModelB model = new OrderModelB(); model.setOrderId(1); model.setOrderName("订单名称"); List goodsList = new ArrayList(); goodsList.add("goods1"); goodsList.add("goods2"); goodsList.add("goods3"); model.setGoodsList(goodsList); model.setAmount(new BigDecimal("10")); model.setType1(1); model.setType2(2); bizValidateService.bizMethodB(model, "param"); } }
3.7 错误信息javax.validation.ConstraintViolationException: bizMethodB.model.typeAndOrderIdComposite: 不满足业务条件 at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:117) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) at com.java.front.validation.BizValidateServiceImpl$EnhancerBySpringCGLIB$7c26a7cb.bizMethodB() at com.java.front.server.TestAuthApplication.testBizValidateB_error(TestAuthApplication.java:94)
4 文章总结
本文第一章节介绍了validation基本概念,第二章节介绍了validation基本应用,第三章节介绍了通过自定义注解动态校验字段,希望本文对大家有所帮助。
欢迎大家关注今日头条号「JAVA前线」查看更多精彩分享文章,主要包括源码分析、实际应用、架构思维、职场分享、产品思考
iPhone15或将采用USBC接口,Lightning接口终于即将要被抛弃苹果近几年的iPhone手机,一直采用的是Lightning接口,由于不能与USBC接口通用,导致在部分情况下充电不是特别方便。不过这一现状即将被打破,据分析师郭明錤最新调查显示,
麻省理工科技评论发布21世纪迄今十大最糟科技必须承认,人类总会犯错,在科技的发展上也是一样。所以,当最新一期的麻省理工科技评论评出今天这份20002019年糟糕科技清单时,你千万不要以为这是一件容易的事情。如果某项科技没有达
文物活了文创火了,新消费浪潮中,阿里创造了什么价值?文谢浩导语从文创产业到母婴室等项目,阿里巴巴逐渐体现出商业价值之外的社会价值,这应该是诸多平台型企业应该追求的目标。前几天,你的朋友圈有没有被一只咖啡杯刷屏?来自星巴克的这款猫爪咖
英特尔又出系统级安全漏洞,暂未修复去年对于英特尔来说是不平凡的一年,现实AMD的Ryzen处理器大放异彩,在市场上获得了众多DIY用户的认可,已经足以与英特尔分庭抗争。而后又是爆出了熔断(Meltdown)和幽灵(
曾经是全球第一PC厂商戴尔据国外媒体报道,上周四电脑行业巨头之一的戴尔科技公司发布2019财年第四季度及全年财报。财报显示,第四季度亏损扩大至2。9亿美元(约19亿元人名币),比去年同期亏损增幅116更让人
事实证明Unity不仅用于游戏还可应用在汽车人工智能和VR领域Unity是一种授权游戏引擎,是世界上最常用的游戏开发软件之一。它也是游戏的Adobe。对于初学者来说,UnityTechnologies的UnityPersonal是一个免费使用
黑客入门十个常用破解网络密码的方法!你了解几个!个人网络密码安全是整个网络安全的一个重要环节,如果个人密码遭到黑客破解,将引起非常严重的后果,例如网络银行的存款被转账盗用,网络游戏内的装备或者财产被盗,QQ币被盗用等等,增强网民
你以为它是一个鼠标垫,其实它还是一个充电宝智能产品是未来的主要发展趋势,为此近些年来的智能产品层出不穷,小米也不甘落后,研发了很多性价比较高的智能产品。而今天我们要为大家介绍的是小米smartpad鼠标垫。该产品荣获201
骁龙845和骁龙855的差距大吗?骁龙855作为骁龙845的继承者,用来取代骁龙845,在CPUGPUAI等方面有了很大的提升,下文对这两款Soc进行对比。CPU方面制造工艺骁龙855基于台积电的7nm制造工艺,骁
用手机修改DNS告别小广告,上网更清爽广告无处不在,看视频听音乐浏览网页都有一些广告,正常的也就罢了,但是有些是别人的没有我的就有广告,一不小心就点到了有色小视频,在公众面前号尴尬。疑似手机中毒,但是杀毒软件查杀不出病
环比下滑552月动力电池装机电量解读高工产业研究院(GGII)通过最新发布的动力电池字段数据库统计显示,2019年2月我国新能源汽车生产约5。3万辆,同比增长43动力电池装机总电量约2。24GWh,同比增长118。值
如何修正华为手机耗电问题?如何修正华为手机耗电问题?耗电问题不仅仅是华为手机,其他的品牌手机也是耗电。手机的应用程序喜欢偷偷的打开,这无疑加大它的耗电。现在的华为手机几乎都升级为鸿蒙系统了。虽然升级后的系统
无聊PK,司马南与浑水公司相比,谁更厉害?国外有家专业公司叫浑水公司,专抖上市公司的黑料,在典型案例中,就有瑞幸咖啡,因为被质疑财务作假,一夜间轰然倒下,从最短上市时间及快速圈钱的神坛拉下去,最终退市,引发陆正耀资本运作一
快手好物联盟升级快分销商家达人有什么红利?经过近三年的高速发展,直播电商行业逐渐进入从求速度到求质量的新竞争时代。11月30日,快手电商分销业务总负责人盖世宣布,好物联盟正式升级为快分销。这是快手电商在三个大搞后的又一新举
数字货币会给我们的生活带来哪些影响?在11月10日,我发表了一篇关注数字货币的文章,表达了在目前国内市场环境下,大家应该对数字货币概念股票进行关注的观点,在前几天数字货币概念的热炒中得到了印证。今天谈谈我对数字货币推
网易云音乐登陆港交所周杰伦入驻云村有望了吗?本报记者谢若琳12月2日,记者打开网易云音乐,喜大普奔云村上市的推荐歌单被放在显眼的位置,该歌单中第一首歌就是好运来。当日上午,有云村之称的网易云音乐以云敲锣的方式登陆港交所,开盘
360大规模侵犯隐私疑云近日,360因宣布正在监控国内私人及企业互联网用户的挖矿IP地址,因而陷入舆论争议。毕竟,监控挖矿与避免侵犯用户隐私如何兼顾,360并没有一个公开明确的说法。当前,中国政府正在加大
最大续航245公里,最高速度70kmh,这3款电动车,适合冬天跑外卖冬天了,外卖小哥比起上班族,更需要抗冻的电动车。哪些电动车天冷的时候续航衰减少,跑得远,跑得快?小编给大家挑了3款适合在冬天跑外卖的电动车,有一款刚进行了极寒挑战,质量靠得住。冷空
美国到中国投资是看准中国人工资低,中国人到美国投资看准美国什么?中国人投资美国看中的是可交易的专利,可融资的华尔街,庞大的市场需求。美国人投资中国看中的是高效率的劳动人口,完整的产业链条,庞大的市场需求。美国人并不是光看中中国人工资低,这很片面
用的是苹果手机,怎么样才能提升其待机时间呢?感谢您的阅读!用的是苹果手机,怎么样提升它的续航时间?苹果手机它本身的优势是在于它的流畅。而苹果手机的劣势是在于它的信号和续航时间。虽然说现在的iPhone13ProMax续航表现
爱奇艺裁员四成节约开支市值逼近万亿,比亚迪高枕无忧?股融易资讯今日话题爱奇艺裁员四成节约开支并整肃灰色收入据晚点LatePost12月1日消息,有七千多名员工的爱奇艺正裁员20至40,涉及多部门多层职级。报道称市场投放渠道合作等部门
为什么网购假货那么多,是什么原因呢?我分享下我刚刚的经历。我从转转平台上买了一个华为66瓦充电器,卖家的文字描述和图片全是华为品牌,35元。我买了之后,到货打开一看是普通超级快充,根本不是华为品牌。我给卖家留言根本不