对表单bean使用基于注释的验证时,对这些bean进行单元测试的最佳实践是什么,以确保为每个字段指定正确的验证注释?
例如,如果您有:
public class MyForm {
@NotNull
private String name;
}
Run Code Online (Sandbox Code Playgroud)
验证@NotNull应用于它的最佳方法是什么?
一个显而易见的方法是创建一个验证器,在它上面抛出一个null并期望它失败.但在我看来,这不是最好的方法,因为你将测试@NotNull使用它的行为和实现,而不是信任框架.
理想情况下,我希望使用反射或实用程序,使我可以断言某个@NotNull(和任何其他)验证应用于给定字段,而不必发送未通过验证的各种值组合.
这样做有一种优雅的方式,还是我一般都在正确的轨道上?
我有一个简单的豆enum田
public class TestBean{
@Pattern(regexp = "A|B") //does not work
private TestEnum testField;
//getters + setters
}
enum TestEnum{
A, B, C, D
}
Run Code Online (Sandbox Code Playgroud)
我想testField使用Bean Validation进行验证.具体来说,我想确保只允许A和B值(对于特定的calidation gropus).似乎enum没有处理JSR 303(我试图使用@Pattern验证器)或者我正在以错误的方式做某事.
我得到例外:
javax.validation.UnexpectedTypeException: No validator could be found for type: packagename.TestEnum
Run Code Online (Sandbox Code Playgroud)
有没有办法验证枚举字段而无需编写自定义验证器?
我正在寻找一种方法来验证java.lang.DoubleSpring命令bean中的字段的最大值和最小值(值必须介于给定的值范围之间),例如,
public final class WeightBean
{
@Max(groups={ValidationGroup.class}, value=Double.MAX_VALUE, message="some key or default message")
@Min(groups={ValidationGroup.class}, value=1D, message="some key or default message")
private Double txtWeight; //Getter and setter.
public interface ValidationGroup{}
}
Run Code Online (Sandbox Code Playgroud)
但两者@Max并@Min不能取java.lang.Double值.
请注意,由于舍入错误,不支持double和float(某些提供程序可能提供一些近似支持)
那么验证这些领域的方法是什么?
我正在使用Spring 3.2.0和Hibernate Validator 4.3.1 CR1.
validation spring spring-mvc hibernate-validator bean-validation
我正在开发一个使用bean验证的项目(Hibernate Validator 5.1.3.Final).我的bean有一个带@Past注释的属性.
@Past(message = "A data deve estar no passado.")
private LocalDate dataAbertura;
Run Code Online (Sandbox Code Playgroud)
但是,当验证发生时,我得到以下异常:
21:46:12,424 ERROR [io.undertow.request] (default task-35) UT005023: Exception handling request to /financeiro/clientes/pessoafisica: javax.servlet.ServletException: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.time.LocalDate.
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:127) [vraptor-4.1.4.jar:]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.1.0.Final.jar:1.1.0.Final] …Run Code Online (Sandbox Code Playgroud) 我下载了spring 3并将它放在我的classpath上,但是我无法导入@Valid注释.但是,我可以导入其他spring 3注释(例如@Controller).什么Jar是@Valid和什么包?
编辑:这是一个JSR-303注释.这是什么意思,我怎么得到它?
这是代码味道,还是以Spring形式实现跨字段验证的最佳方式?
@FieldRequiredIf.List({
@FieldRequiredIf(ifField="firstHomePhoneNumber", matches={EMPTY, NULL},require ="firstMobilePhoneNumber",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.firstMobilePhoneNumber",groups=FirstLife.class),
@FieldRequiredIf(ifField="secondHomePhoneNumber", matches={EMPTY,NULL},require ="secondMobilePhoneNumber",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.secondMobilePhoneNumber",groups=SecondLife.class),
@FieldRequiredIf(ifField="lifeAssuredIsPolicyOwner", matches={FALSE},require ="policyOwnerName",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.policyOwnerName"),
@FieldRequiredIf(ifField="lifeAssuredIsPolicyOwner", matches={FALSE},require ="policyOwnerAddress",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.policyOwnerAddress"),
@FieldRequiredIf(ifField="insurableInterest", matches={InsurableInterestConstants.OTHER},require ="insurableInterestReason",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.insurableInterestReason",groups = NonSingleNonMortgage.class),
@FieldRequiredIf(ifField="firstAddress2", matches={NOT_EMPTY},require ="firstAddress1",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.firstAddress1",groups=FirstLife.class),
@FieldRequiredIf(ifField="firstAddress3", matches={NOT_EMPTY},require ="firstAddress2",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.firstAddress2",groups=FirstLife.class),
@FieldRequiredIf(ifField="firstAddress4", matches={NOT_EMPTY},require ="firstAddress3",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.firstAddress3",groups=FirstLife.class),
@FieldRequiredIf(ifField="firstAddress5", matches={NOT_EMPTY},require ="firstAddress4",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.firstAddress4",groups=FirstLife.class),
@FieldRequiredIf(ifField="secondAddress2", matches={NOT_EMPTY},require ="secondAddress1",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.secondAddress1",groups=SecondLife.class),
@FieldRequiredIf(ifField="secondAddress3", matches={NOT_EMPTY},require ="secondAddress2",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.secondAddress2",groups=SecondLife.class),
@FieldRequiredIf(ifField="secondAddress4", matches={NOT_EMPTY},require ="secondAddress3",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.secondAddress3",groups=SecondLife.class),
@FieldRequiredIf(ifField="secondAddress5", matches={NOT_EMPTY},require ="secondAddress4",elseDisplay = "FieldRequiredIf.correspondenceDetailsForm.secondAddress4",groups=SecondLife.class)
})
public class CorrespondenceDetailsForm {
...
}
Run Code Online (Sandbox Code Playgroud)
为了简化上述操作,我开始将这些列出的注释的几个逻辑组重构为单个自定义注释:(@ FirstLifeContactDetailsObserver和@SecondLifeContactDetailsObserver).这是重构的类级别注释: …
我使用JSF 2.0和RichFaces 4创建了一个基于MVC的网站.每个输入文本验证都是使用bean验证注释完成的.我使用Hibernate Validator作为bean验证实现.
如何显示本地化消息?
如果我使用
@NotNull(message="<h:outputText value=\"#{msg['Mymessage']}\" />")
Run Code Online (Sandbox Code Playgroud)
然后它字面上显示<h:outputText value="#{msg['Mymessage']}" />为消息.

这是怎么造成的,我该如何解决?
我在Spring控制器中有以下代码:
@Autowired
private javax.validation.Validator validator;
@RequestMapping(value = "/submit", method = RequestMethod.POST)
public String submitForm(CustomForm form) {
Set<ConstraintViolation<CustomForm>> errors = validator.validate(vustomForm);
...
}
Run Code Online (Sandbox Code Playgroud)
是否可以映射errors到Spring的BindingResult对象而无需手动完成所有错误并将其添加到BindingResult?像这样的东西:
// NOTE: this is imaginary code
BindingResult bindingResult = BindingResult.fromConstraintViolations(errors);
Run Code Online (Sandbox Code Playgroud)
我现在可以用CustomForm参数注释@Valid并让Spring注入BindingResult另一个方法的参数,但在我的情况下它不是一个选项.
// I know this is possible, but doesn't work for me
public String submitForm(@Valid CustomForm form, BindingResult bindingResult) {
...
}
Run Code Online (Sandbox Code Playgroud) 例:
public String getStudentResult(@RequestParam(value = "regNo", required = true) String regNo, ModelMap model){
Run Code Online (Sandbox Code Playgroud)
如何在此处使用@valid作为regNo参数?
当我在 javax.validations 中使用 @valid 注释验证 bean 时,对于某些对象,我收到 ConstraintViolationException,而对于某些对象,我收到 MethodArgumentNotValidException。
我明白,如果我在 controller 处验证 @ResponseBody 中的任何内容,它会抛出 MethodArgumentNotValidException。
但是对于类级别的某些自定义验证(例如@MyCustomValidation),即使在@ResponseValidation 中对其进行验证,它也会抛出ConstraintViolationException。
对于不同 REST 端点的其他一些自定义验证,它会抛出 MethodArgumentNotValidException。
我发现它有点难以理解,因为它是一种行为。
@PostMapping(path = "/someEndPoint")
@Validated(OnASave.class)
public ResponseEntity<ClassA> saveObjA(@Valid @RequestBody ClassA objA)
Run Code Online (Sandbox Code Playgroud)
结果 - 抛出 MethodArgumentNotValidException
@PostMapping(path = "/someOtherEndPoint")
@Validated(OnBSave.class)
public ResponseEntity<ClassB> saveObjB(@Valid @RequestBody ClassB objB)
Run Code Online (Sandbox Code Playgroud)
结果 - 抛出 ConstraintViolationException
ClassA 和 ClassB 都有自定义验证。
bean-validation ×10
java ×7
spring ×5
spring-mvc ×5
validation ×3
annotations ×2
java-ee ×2
forms ×1
java-ee-6 ×1
java-ee-7 ×1
jsf-2 ×1
jsr ×1
localization ×1
richfaces ×1
unit-testing ×1