Java 如何组合验证两个或多个字段?
我正在使用JPA2.0/Hibernate验证来验证我的模型。我现在遇到一种情况,必须验证两个字段的组合:Java 如何组合验证两个或多个字段?,java,jpa,jpa-2.0,bean-validation,Java,Jpa,Jpa 2.0,Bean Validation,我正在使用JPA2.0/Hibernate验证来验证我的模型。我现在遇到一种情况,必须验证两个字段的组合: public class MyModel { public Integer getValue1() { //... } public String getValue2() { //... } } 如果getValue1()和getValue2()都是null则模型无效,否则有效 如何使用JPA2.0/Hibernate执行这
public class MyModel {
public Integer getValue1() {
//...
}
public String getValue2() {
//...
}
}
如果getValue1()
和getValue2()
都是null
则模型无效,否则有效
如何使用JPA2.0/Hibernate执行这种验证?对于一个简单的
@NotNull
注释,两个getter都必须为非null才能通过验证。对于多属性验证,应该使用类级约束。从…起
:
类级约束
你们中的一些人表达了担忧
关于应用程序的能力
跨越多重约束
属性,或表示约束
这取决于几个属性。
经典的例子是地址
验证。地址有复杂的含义
规则:
- 街道名称在某种程度上是标准的,必须有长度限制
- 邮政编码结构完全取决于国家
- 城市通常可以与zipcode关联,并且可以进行一些错误检查 完成(前提是验证 服务(无障碍)
- 由于这些相互依赖性,一个简单的属性级别约束不起作用 符合要求
- 它提供了一种能力,可以强制一组约束在 通过 使用组和组序列。 本课程将涵盖这一主题 下一篇博客
- 它允许定义类级别的约束
中的属性值)无效
@AddressAnnotation
public class Address {
@NotNull @Max(50) private String street1;
@Max(50) private String street2;
@Max(10) @NotNull private String zipCode;
@Max(20) @NotNull String city;
@NotNull private Country country;
...
}
@Constraint(validatedBy = MultiCountryAddressValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AddressAnnotation {
String message() default "{error.address}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public class MultiCountryAddressValidator implements ConstraintValidator<AddressAnnotation, Address> {
public void initialize(AddressAnnotation constraintAnnotation) {
// initialize the zipcode/city/country correlation service
}
/**
* Validate zipcode and city depending on the country
*/
public boolean isValid(Address object, ConstraintValidatorContext context) {
if (!(object instanceof Address)) {
throw new IllegalArgumentException("@Address only applies to Address");
}
Address address = (Address) object;
Country country = address.getCountry();
if (country.getISO2() == "FR") {
// check address.getZipCode() structure for France (5 numbers)
// check zipcode and city correlation (calling an external service?)
return isValid;
} else if (country.getISO2() == "GR") {
// check address.getZipCode() structure for Greece
// no zipcode / city correlation available at the moment
return isValid;
}
// ...
}
}
@AddressAnnotation
公共课堂演讲{
@NotNull@Max(50)专用字符串street1;
@最多(50)条私人字符串街2;
@最大(10)@NotNull私有字符串zipCode;
@最大值(20)@NotNull字符串城市;
@非空私人国家;
...
}
@约束(validatedBy=MultiCountryAddressValidator.class)
@目标(ElementType.TYPE)
@保留(RetentionPolicy.RUNTIME)
公共@接口地址注释{
字符串消息()默认值“{error.address}”;
类[]组()默认值{};
类例如,当您想继续使用Bean验证规范时,定制类级验证器是一种选择
如果您愿意使用Hibernate Validator功能,您可以使用,它是从Validator-4.1.0.Final.Exceprt的JavaDoc中提供的:
脚本表达式可以用任何脚本或表达式编写
语言,其中一个是(“JavaTM平台脚本”)
在类路径上可以找到兼容的引擎
例如:
@ScriptAssert(lang=“javascript”,script=“_this.value1!=null | | | u this!=value2”)
公共类MyBean{
私有字符串值1;
私有字符串值2;
}
为了正确使用,Pascal Thivent中提供的示例可以重写如下:
@ValidAddress
公共课堂演讲{
@NotNull
@尺寸(最大值=50)
私家弦街1号;
@尺寸(最大值=50)
私家弦街2号;
@NotNull
@尺寸(最大值=10)
私有字符串zipCode;
@NotNull
@尺寸(最大值=20)
私人城市;
@有效的
@NotNull
私人国家;
//接球手和接球手
}
公共类国家{
@NotNull
@尺寸(最小值=2,最大值=2)
私有字符串iso2;
//接球手和接球手
}
@已记录
@目标(类型)
@保留(运行时)
@约束(validatedBy={MultiCountryAddressValidator.class})
public@interface-ValidAddress{
String message()默认值“{com.example.validation.ValidAddress.message}”;
类[]组()默认值{};
类编程语言:Java
这是一个帮助我的解决方案
要求:
在UI上有一个表,其中包含对象列表,这些对象正在映射到具有fk关系的多个表/对象
现在验证是在多个FK中进行的,只有3个列不能重复。我的意思是3个列的组合不能重复
注意:当我在Java上使用自定义框架时,没有使用HashCode或equals的选项。如果我使用数组索引迭代,这将增加我不希望的时间复杂性
解决方案:
我准备了一个字符串,它是一个自定义字符串,包含FK1的ID#FK2的ID#FK3的ID
例如:字符串将形成->1000L#3000L#1300L#
对于这个字符串,我们将使用set的add()将其添加到一个集合中,如果出现重复,该集合将返回false
基于此标志,我们可以抛出验证消息
这对我很有帮助。有些场景和限制是DS可能没有帮助的。是的,Java 6包括Rhino(JavaScript引擎)因此,您可以使用JavaScript作为表达式语言,而无需添加额外的依赖项。这是一个如何使用Hibernate Validator 5.1.1创建此类验证的示例。在示例中,接口ConstraintValidator和注释@Constraint的最终可能副本已反转。并且是valid()接受2个参数。TYPE
和RUNTIME
应分别替换为ElementType.TYPE
和RetentionPolicy.RUNTIME
。@mark.monteiro您可以使用静态导入:导入静态java.lang.annotation.ElementType.*;
和导入静态java.lang.annotation.RetentionPolicy.*;
I“我已经重写了这个示例来使用Bean验证。看一看。注释的参数不在规范范围内,因为必须有一条消息、组和负载,就像Cassio在这个回答中提到的那样。如何在一个WebSphere restful项目中为CDI Bean引导或调用自定义验证器?我有