【发布时间】:2013-02-20 01:51:21
【问题描述】:
我正在使用HibernateValidator 4.3.1。在整个应用程序中按预期执行验证。
我已经注册了一些自定义编辑器来执行全局验证,例如确保文本字段中的数值(double、int 等),确保有关 Joda-Time API 的有效日期等。
在这种类型的验证中,我允许空值/空值,方法是像往常一样将 allowEmpty 参数设置为 false 以单独验证它,特别是当这些字段留空时显示单独的用户友好错误消息。
因此,除了使用 HibernateValidator 和自定义编辑器进行验证之外,我还尝试使用以下验证策略。同样,这种验证仅适用于为自定义编辑器注册的字段留空。
以下是实现org.springframework.validation.Validator接口的类。
package test;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import validatorbeans.TempBean;
@Component
public final class TempValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
System.out.println("supports() invoked.");
return TempBean.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
TempBean tempBean = (TempBean) target;
System.out.println("startDate = " + tempBean.getStartDate() + " validate() invoked.");
System.out.println("doubleValue = " + tempBean.getDoubleValue() + " validate() invoked.");
System.out.println("stringValue = " + tempBean.getStringValue() + " validate() invoked.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "java.util.date.nullOrEmpty.error");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "doubleValue", "java.lang.double.nullOrEmpty.error");
}
}
该类使用@Component 注释指定,以便它可以自动连接到特定的 Spring 控制器类。调试语句完全根据用户提供的输入显示。
以下是控制器类。
package controller;
import customizeValidation.CustomizeValidation;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.groups.Default;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import test.TempValidator;
import validatorbeans.TempBean;
@Controller
public final class TempController {
@Autowired
private TempService tempService;
private TempValidator tempValidator;
public TempValidator getTempValidator() {
return tempValidator;
}
@Autowired
public void setTempValidator(TempValidator tempValidator) {
this.tempValidator = tempValidator;
}
@RequestMapping(method = {RequestMethod.GET}, value = {"admin_side/Temp"})
public String showForm(@ModelAttribute("tempBean") @Valid TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) {
return "admin_side/Temp";
}
@RequestMapping(method = {RequestMethod.POST}, value = {"admin_side/Temp"})
public String onSubmit(@ModelAttribute("tempBean") @Valid TempBean tempBean, BindingResult errors, Map model, HttpServletRequest request, HttpServletResponse response) {
//tempValidator.supports(TempBean.class);
//tempValidator.validate(tempBean, errors);
DataBinder dataBinder = new DataBinder(tempBean);
dataBinder.setValidator(tempValidator);
dataBinder.validate();
//errors=dataBinder.getBindingResult();
if (CustomizeValidation.isValid(errors, tempBean, TempBean.ValidationGroup.class, Default.class) && !errors.hasErrors()) {
System.out.println("Validated");
}
return "admin_side/Temp";
}
}
我正在通过
从 Spring 控制器类本身(我确实想要)调用验证器DataBinder dataBinder = new DataBinder(tempBean);
dataBinder.setValidator(tempValidator);
dataBinder.validate();
验证器被调用,但预期的验证未执行。
如果我只使用以下语句(上面已注释掉)手动调用验证器,
tempValidator.validate(tempBean, errors);
然后执行验证。所以我不相信我的验证器工作正常。为什么它无法与DataBinder 一起使用?
在我的application-context.xml文件中,这个bean简单配置如下。
<bean id="tempValidator" class="test.TempValidator"/>
自动检测到以下许多包,包括 TempValidator 类包含在其中的 test 包。
<context:component-scan base-package="controller spring.databinder validatorbeans validatorcommands test" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
<context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>
</context:component-scan>
我什至试过把
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
在我的dispatcher-servlet.xml 文件中。
我在这里俯瞰什么?
【问题讨论】:
-
如果你在“dataBinder.validate();”这一行打了个断点走进去,你能看到最终调用的是哪个验证器吗?
-
@CodeChimp - 调用的验证器是问题中指定的验证器 -
tempValidator。
标签: spring spring-mvc bean-validation spring-3 hibernate-validator