【问题标题】:Spring 3 validation not workingSpring 3 验证不起作用
【发布时间】:2011-09-07 19:48:18
【问题描述】:

我的应用程序中有一个需要验证的用户实体。

public class User {

private String userName;
private String password;

public void setUserName(String userName){
this.userName = userName;
}

public getUserName(){
return this.userName;
}   

// and so on 

}

为此,我创建了如下所示的 UsersValidator。

public class UserValidator implements Validator {

public boolean supports(Class clazz) {
    return User.class.equals(clazz);
}

public void validate(Object obj, Errors errors) {
    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "field.required");
    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "field.required");
}
}

我有一个这样的控制器

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String home(@Valid User user,
        BindingResult result) {

    if (result.hasErrors()) {
        return "loginForm";
    } else {
    //continue
}

}

绑定结果没有任何错误。

我还需要做什么才能使验证生效?我是否对控制器或弹簧配置文件进行了任何更改。

<mvc:annotation-driven />

<context:component-scan base-package="com.myapp" />

<mvc:resources location="/resources/" mapping="/resources/**" />

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass">
        <value>org.springframework.web.servlet.view.tiles2.TilesView</value>
    </property>
</bean>

<bean id="tilesConfigurer"
    class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/tiles.xml</value>
        </list>
    </property>
</bean>

<bean id="messageSource"
    class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>com/dimex/resourceBundles/ApplicationResources</value>
            <value>com/dimex/resourceBundles/errors</value>
        </list>
    </property>            
  </bean>

<mvc:interceptors>  
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="locale"></property>
    </bean>
</mvc:interceptors>

<bean id="localeResolver"
    class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    <property name="defaultLocale" value="en" />
</bean>

编辑:-

我需要在我的类路径中有休眠验证器吗?我们没有在我们的应用程序中使用休眠。 请帮忙。

EDIT2:-

当我直接在我的实体类中使用验证注释(@NotNull、@Size 等)时,控制器中的 @Valid 注释可以工作,但如果我从实体中删除它们并尝试使用上面编写的验证器,那么 @Valid 不起作用.

是不是@Valid 注释只适用于实体中的验证注释而不适用于验证器?为了使用我的验证器,我必须直接在验证器中调用 validate 方法吗?

【问题讨论】:

  • 你配置spring来实例化UserValidator了吗?例如,通过使用@Component 注释验证器?如果使用 @NotNull 注释 bean 上的字段,也可以实现几乎相同的行为。
  • @Augusto 我已经添加了@Component 但它仍然无法正常工作!!!!!!
  • 您还需要&lt;context:component-scan/&gt; 才能获取@Components。你有这个吗?如果你发布你的 Spring XML 会更容易。
  • @matt b 我已经用 Spring xml 更新了这个问题。
  • 如果我明确执行 this.validator.validate(user, result);那么它的工作,但如果我使用@Valid 那么它不工作。

标签: java validation spring-mvc


【解决方案1】:

据我了解,您正在尝试将 JSR-303 @Valid 注释与经典的弹簧验证结合起来。你为什么想做这个? UserValidator 类的等效 JSR-303 注释如下所示:

@NotNull
@Size(min=1)
private String userName;

@NotNull
@Size(min=1)
private String password

...

spring documentation 说明了配置 JSR-303 验证所需的步骤。您需要hibernate-validator(或其他 JSR-303 提供者)才能使上述内容正常工作。您还需要配置validator bean,如下所示。

<bean id="validator"
      class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

这个问题的其他答案也在同一行。

【讨论】:

  • 有没有办法不使用Size注解?
  • 这对我帮助很大!!添加 hibernate-validator
【解决方案2】:

您需要使用@InitBinder 注解定义要在控制器中使用的验证器,例如:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.setValidator(new UserValidator());
}

【讨论】:

  • 我认为你需要用你需要验证的对象的名称来注释@InitBinder。例如@InitBinder("user").
  • 你的路径上有 Hibernate Validator 吗?
  • @Dave 我的路径上没有 Hibernate 验证器。我需要一个吗?我没有在我的应用程序中使用 Hibernate
  • 是的,您需要 Hibernate Validator,因为这会添加 @Valid 标记的实现。
  • 你有没有把 Hibernate Validator 放在你的路径上?这是必需的。
【解决方案3】:

其他方法是从您的控制器调用 spring 验证器初始化

DataBinder dataBinder = new DataBinder(user);
dataBinder.setValidator(userValidator);
dataBinder.validate();

BindingResult result = dataBinder.getBindingResult();

if(result.hasErrors() == false) {
   // error exists
} 

【讨论】:

  • 有没有办法可以将@Valid 与验证器类一起使用?
  • 我从来没有这样用过。我使用 @Valid 进行模型验证,使用 initbinder 进行特定验证 - 前端、休息服务等。您可以在此处查看此线程 - forum.springsource.org/… 您需要使用 initBinder 注释才能使其正常工作。
  • 这种手动方法对我有用。但是在模型类上使用 @Valid 注释不会触发我的验证,BindingResult 显示 0 个错误。有什么提示吗?
  • DataBinder是一个接口,你怎么能像new DataBinder(user)这样实例化呢?
【解决方案4】:

您需要将@Component 放在Validator 实现上,以便Spring 容器可以将其识别为:

@Component
public class UserValidator implements Validator {

并在控制器中使用以下方法:

@InitBinder(用户VO) protected void initBinder(WebDataBinder binder) { binder.setValidator(userValidator); }

【讨论】:

    【解决方案5】:

    如果您在 Spring 中使用 JSR-303 样式的验证(即由 JSR-303 实现提供的全局验证器实例,例如 Hibernate Validator),并且您有一个 @InitBinder-annotated在你的Controller 方法中,你必须Validator 注入你的控制器@InitBinder 方法中设置它:

    @Autowired
    public void setValidator(Validator validator) {
        this.validator = validator;
    }
    
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(this.validator);
    }
    

    WebDataBinder 的验证器默认设置为 null,而不是(如您所料)全局 JSR-303 验证器实例,因此您的模型不会被 Spring 验证除非您在此处手动设置 Validator 实例

    只有当你有一个@InitBinder 方法时。如果您不这样做,一切都会按预期进行。

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 2017-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多