我有一个由许多字段组成的类,这些字段具有
hibernate-validator Annotations
,因此如果输入无效数据,它可以抛出相应的消息。
某些字段是相互依赖的,这意味着如果另一个字段具有特定值,则该字段必须为非空。有没有办法直接使用
hibernate-validator
来实现这一点,还是我们需要为其编写自定义验证?
@Data
@ToString
public class Source implements Serializable {
@NotNull(message = "Type cannot be Null for source")
private String type;
//If type has any value apart from "MANUAL" then this should not be NULL @NotNull(message = "groundValue cannot be Null")
private String groundValue;
//If type value is "MANUAL" then this should not be NULL @NotNull(message = "manualType value cannot be Null")
private String manualType;
//If type value is "MANUAL" then this should not be NULL @NotNull(message = "manualURI value cannot be Null")
private String manualURI;
}
如上面代码中所述,如果
groundValue
、manualType
和 manualURI
的条件基于提供给 type
的值,则会被剪断。
是否可以直接使用
Javax valdidation
实现类似的效果?以下是我在项目中使用的 Maven 依赖项:
<!-- For adding the validation annotations -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
是的,您可以创建自己的验证器。
package spike;
public interface ISource {
String getType();
String getGroundValue();
String getManualType();
String getManualURI();
}
package spike;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
@SourceType
public class Source implements Serializable, ISource {
@NotNull(message = "Type cannot be Null for source")
private String type;
//If type has any value apart from "MANUAL" then this should not be NULL @NotNull(message = "groundValue cannot be Null")
private String groundValue;
//If type value is "MANUAL" then this should not be NULL @NotNull(message = "manualType value cannot be Null")
private String manualType;
//If type value is "MANUAL" then this should not be NULL @NotNull(message = "manualURI value cannot be Null")
private String manualURI;
@Override
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String getGroundValue() {
return groundValue;
}
public void setGroundValue(String groundValue) {
this.groundValue = groundValue;
}
@Override
public String getManualType() {
return manualType;
}
public void setManualType(String manualType) {
this.manualType = manualType;
}
@Override
public String getManualURI() {
return manualURI;
}
public void setManualURI(String manualURI) {
this.manualURI = manualURI;
}
@Override
public String toString() {
return "Source{" +
"type='" + type + '\'' +
", groundValue='" + groundValue + '\'' +
", manualType='" + manualType + '\'' +
", manualURI='" + manualURI + '\'' +
'}';
}
}
package spike;
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;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SourceTypeValidator.class)
public @interface SourceType {
String message() default "{SourceTypeError}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package spike;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class SourceTypeValidator implements ConstraintValidator<SourceType, ISource> {
private String message;
@Override
public void initialize(SourceType constraintAnnotation) {
message = constraintAnnotation.message();
}
@Override
public boolean isValid(ISource value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
if ("MANUAL".equals(value.getType())) {
return true;
}
boolean valid = true;
if (value.getGroundValue() == null) {
addConstraintViolation(context, "groundValue");
valid = false;
}
if (value.getManualType() == null) {
addConstraintViolation(context, "manualType");
valid = false;
}
if (value.getManualURI() == null) {
addConstraintViolation(context, "manualURI");
valid = false;
}
return valid;
}
private void addConstraintViolation(ConstraintValidatorContext context, String p) {
context.buildConstraintViolationWithTemplate(p + " cannot be Null")
.addPropertyNode(p)
.addConstraintViolation();
}
}
可以使用 SpELScriptAssert 库轻松完成。顺便说一句,我是这个库的作者。这是示例代码:
@SpELScriptAssert(
script = "groundValue != null",
performIf = "type != 'MANUAL'",
reportOn = "groundValue",
message = "{reportOn} cannot be Null")
@SpELScriptAssert(
script = "manualType != null",
performIf = "type == 'MANUAL'",
reportOn = "manualType",
message = "{reportOn} cannot be Null")
@SpELScriptAssert(
script = "manualURI != null",
performIf = "type == 'MANUAL'",
reportOn = "manualURI",
message = "{reportOn} cannot be Null")
public class Source implements Serializable {
@NotNull(message = "Type cannot be Null for source")
public String type;
public String groundValue;
public String manualType;
public String manualURI;
}
}