将Spring的LocalValidatorFactoryBean与JSF一起使用 [英] Using Spring's LocalValidatorFactoryBean with JSF

查看:443
本文介绍了将Spring的LocalValidatorFactoryBean与JSF一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将一个bean注入到一个自定义的ConstraintValidator中.我遇到了一些事情:

I am trying to get a bean injected into a custom ConstraintValidator. I have come across some things:

  • validation-api-1.1.0(支持Beta版)支持CDI
  • Hibernate Validator 5似乎实现了validate-api-1.1.0(可使用Alpha版)
  • 使用Seam验证模块
  • 使用Spring的LocalValidatorFactoryBean

最后一个似乎最适合我的情况,因为我们已经在使用Spring(3.1.3.Release).

The last one seems most appropriate for my situation since we're already using Spring (3.1.3.Release).

我已经将验证器工厂添加到XML应用程序上下文中,并且启用了注释:

I have added the validator factory to the XML application context and annotations are enabled:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <context:component-scan base-package="com.example" />
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
</beans>

验证者:

public class UsernameUniqueValidator implements
    ConstraintValidator<Username, String>
{
    @Autowired
    private PersonManager personManager;

    @Override
    public void initialize(Username constraintAnnotation)
    {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context)
    {
        if (value == null) return true;
        return personManager.findByUsername(value.trim()) != null;
    }
}

验证适用于Person:

public class Person
{
    @Username
    private String username;
}

还有后备豆:

@Named
@Scope("request")
public class PersonBean
{
    private Person person = new Person();
    @Inject
    private PersonManager personManager;

    public create()
    {
        personManager.create(person);
    }
}

在JSF页面中,我有:

And in the JSF page I have:

<p:inputText value="#{personBean.person.username}" />

调用验证器,但该字段未自动装配/插入,并且保持为空.当然,这引发了NullPointerException.

The validator is invoked but the field is not autowired/injected and stays null. This of course trows a NullPointerException.

我正在使用Hibernate验证程序4.2对此进行测试(因为我认为LocalValidatorFactoryBean应该能够做到).

I am testing this with Hibernate validator 4.2 (since LocalValidatorFactoryBean should be able to do this I think).

推荐答案

肯定是使用键BeanValidator.VALIDATOR_FACTORY_KEY将自己的自定义ValidatorFactory添加到应用程序映射中的方法. 但是您也可以从春季开始使用它,而不是使用javax.faces.event.SystemEventListener.将ValidatorFactory注册为ServletContext中的属性就足以将其拾取并添加到应用程序映射中(这是ServletContext或PortletContext的抽象,无论使用什么方式).

It is definately the way to go to add your own custom ValidatorFactory to the application map using the key BeanValidator.VALIDATOR_FACTORY_KEY. But instead of using a javax.faces.event.SystemEventListener, you could also approach it from the spring side. Registering your ValidatorFactory as an attribute in the ServletContext will be enough for it to be picked up and added to the application map (which is an abstraction for either the ServletContext or PortletContext, whatever you are using).

所以问题是:如何将spring bean作为属性添加到ServletContext.我的解决方案是使用实现ServletContextAware的辅助bean:

So the question is: how to add a spring bean as an attribute to the ServletContext. My solution was to use a helper bean that implements ServletContextAware:

public class ServletContextAttributePopulator implements ServletContextAware {

    Map<String,Object> attributes;

    public Map<String, Object> getAttributes() {
        return attributes;
    }

    public void setAttributes(Map<String, Object> attributes) {
        this.attributes = attributes;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        for (Map.Entry<String,Object> entry : attributes.entrySet()) {
            servletContext.setAttribute(entry.getKey(), entry.getValue());
        }
    }

}

请注意,可以将此类用于要添加到ServletContext的任何类型的bean.
在您的春季背景下,您可以添加:

Note that you could use this class for any type of bean you want to add to the ServletContext.
In your spring context, you would then add:

<bean  id="servletContextPopulator" class="my.package.ServletContextAttributePopulator">
    <property name="attributes">
    <map>
        <entry key="javax.faces.validator.beanValidator.ValidatorFactory" value-ref="validator"/>
    </map>
    </property>
</bean>

其中验证器"是您的LocalValidatorFactoryBean的ID.

where "validator" is the id of your LocalValidatorFactoryBean.

这篇关于将Spring的LocalValidatorFactoryBean与JSF一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆