Pertanyaan Hibernate Validator, Custom ResourceBundleLocator dan Spring


Saya mencoba mengganti ResourceBundleLocator default dalam validasi hibernate 4.1. Sejauh ini bekerja dengan sempurna, tetapi satu-satunya contoh penggunaannya termasuk kode java untuk instantiate ValidationFactory.

Saat menggunakan aplikasi web dengan validasi musim semi hibernasi secara otomatis dikonfigurasi (hanya file validasi hibernate * .jar yang sesuai harus ada dan secara otomatis digunakan). Bagaimana saya bisa mengganti ResourceBundleLocator dalam skenario itu? Saya tidak melihat cara specyfing ResourceBundleLocator kustom saya di setiap properti atau file applicationContext.xml.


9
2017-11-15 16:32


asal


Jawaban:


Metode ajaib yang melakukan pekerjaan yang diminta adalah LocalValidatorFactoryBean # setValidationMessageSource (MessageSource messageSource).

Pertama-tama, kontrak metode: -

Tentukan Spring Messeource khusus untuk menyelesaikan validasi     pesan, alih-alih mengandalkan     Default JSR-303     Paket "ValidationMessages.properties"     di dalam classpath. Ini bisa merujuk pada a     Konteks musim semi dibagikan     "messageSource" kacang, atau beberapa     pengaturan MessageSource khusus untuk     hanya validasi tujuan.

CATATAN: Fitur ini memerlukan Hibernasi   Validator 4.1 atau lebih tinggi pada   classpath. Anda tetap dapat menggunakan   penyedia validasi yang berbeda tetapi   Hibernate Validator   ResourceBundleMessageInterpolator   kelas harus dapat diakses selama   konfigurasi.

Tentukan apakah properti ini atau   "messageInterpolator", tidak keduanya. Jika   Anda ingin membuat suatu kebiasaan   MessageInterpolator, pertimbangkan untuk turun   dari Hibernate Validator   ResourceBundleMessageInterpolator dan   lewat di Musim Semi   MessageSourceResourceBundleLocator   saat membangun interpolator Anda.

Anda dapat menentukan pesan khusus Anda.properti (atau .xml) dengan menerapkan metode ini ... seperti ini ...

my-beans.xml

<bean name="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource">
        <ref bean="resourceBundleLocator"/>
    </property>
</bean>

<bean name="resourceBundleLocator" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>META-INF/validation_errors</value>
        </list>
    </property>
</bean>

validation_errors.properties

javax.validation.constraints.NotNull.message=MyNotNullMessage

Person.java

    class Person {
    private String firstName;
    private String lastName;

    @NotNull
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

BeanValidationTest.java

    public class BeanValidationTest {

    private static ApplicationContext applicationContext; 

    @BeforeClass
    public static void initialize() {
        applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/spring/webmvc-beans.xml");
        Assert.assertNotNull(applicationContext);
    }

    @Test
    public void test() {
        LocalValidatorFactoryBean factory = applicationContext.getBean("validator", LocalValidatorFactoryBean.class);
        Validator validator = factory.getValidator();
        Person person = new Person();
        person.setLastName("dude");
        Set<ConstraintViolation<Person>> violations = validator.validate(person);
        for(ConstraintViolation<Person> violation : violations) {
            System.out.println("Custom Message:- " + violation.getMessage());
        }
    }

}

Outupt:  Custom Message:- MyNotNullMessage


18
2017-11-22 16:13



Berikut ini adalah solusi jika Anda ingin mencampur pesan validasi hibernate yang ada dan pesan validasi kustom:

<mvc:annotation-driven validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames" value="i18n,iso-i18n,org.hibernate.validator.ValidationMessages" />
    <property name="useCodeAsDefaultMessage" value="true" />
</bean>

(Lihat Kerangka kerja kerangka MVC Web dan Mengkonfigurasi Penyedia Validasi Bean dalam dokumentasi Spring)


5
2018-03-26 08:33



Terima kasih @ Lu55, berdasarkan jawaban Anda, saya memecahkan masalah saya !!

Saya baru saja mengkonversikan ke kelas Konfigurasi, dan saya memposting di sini untuk berjaga-jaga jika ada orang lain yang membutuhkan:

Detail impor: berfungsi untuk saya dengan ReloadableResourceBundleMessageSource, tetapi tidak berfungsi menggunakan ResourceBundleMessageSource. Saya tidak yakin mengapa.

@Configuration
public class ErrorConfig {

    @Bean
    public Validator validatorFactory (MessageSource messageSource) {
        LocalValidatorFactoryBean validator =  new LocalValidatorFactoryBean();
        validator.setValidationMessageSource(messageSource);
        return validator;
    }

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
        bean.addBasenames("classpath:org.hibernate.validator.ValidationMessages","classpath:message");
        bean.setDefaultEncoding("UTF-8");
        return bean;
    }
}

Di dalam folder sumber daya saya, saya memiliki file message.properties.


0
2017-07-31 10:01