开发者

How do I retrieve default validation messages from Hibernate Validator?

I'm trying to retrieve a default validation error-message using MessageSource. The code I'm working with uses reflection to retrieve the value of the message parameter. On a constraint that does not override the message parameter, I would like to retrieve the def开发者_开发问答ault error message. When I invoke the message method on the validation annotation, I get {org.hibernate.validator.constraints.NotBlank.message} (for example, for the @NotBlank annotation). I then tried to use MessageSource to get the error message like so:

String message = messageSource.getMessage(key, null, Locale.US);

I tried setting key to {org.hibernate.validator.constraints.NotBlank.message}, org.hibernate.validator.constraints.NotBlank.message (removed braces) and even org.hibernate.validator.constraints.NotBlank but I keep getting null. What am I doing wrong here?

UPDATE

A clarification. I am under the impression that Spring comes with a default message.properties file for its constraints. Am I correct in this assumption?

UPDATE

Changing the name of the question to better reflect what I was trying to do.


After running into a blog post from one of the Hibernate guys, and after digging around in the Hibernate Validator source, I think I've figured it out:

public String getMessage(final Locale locale, final String key) {
    PlatformResourceBundleLocator bundleLocator = new PlatformResourceBundleLocator("org.hibernate.validator.ValidationMessages");
    ResourceBundle resourceBundle = bundleLocator.getResourceBundle(locale);

    try {
       final String k = key.replace("{", "").replace("}", "");
       return resourceBundle.getString(k);
    }
    catch (MissingResourceException e) {
       return key;
    }
}

So first, you have to instantiate a PlatformResourceBundleLocator with the default validation messages. Then you retrieve a ResourceBundle from the locator and use that to get your message. I don't believe this performs any interpolation though. For that you have to use an interpolator; the blog post I linked to above goes into more detail about that.

UPDATE

Another (easier) way is to update your applicationContext.xml and do this:

<bean id="resourceBundleSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>org.hibernate.validator.ValidationMessages</value>
        </list>
    </property>
</bean>

Now your MessageSource is populated with the default messages and you can do messageSource.getMessage(). In fact, this is probably the best way.


Spring Boot 2.4.5

In case someone needs this for testing:

package some.package;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Locale;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.MessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

public class NotNullTest {

  private static MessageSource ms;
  private static String VAL_MSG_NOT_NULL;

  @BeforeAll
  static void setUpClass() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("org/hibernate/validator/ValidationMessages");
    messageSource.setDefaultEncoding("UTF-8");
    ms = messageSource;
  }

  @BeforeEach 
  void setUp() {
    VAL_MSG_NOT_NULL = ms.getMessage("javax.validation.constraints.NotNull.message", null, Locale.ROOT);
    assertThat(VAL_MSG_NOT_NULL).isNotNull();
    assertThat(VAL_MSG_NOT_NULL).isNotBlank();
  }

  @Test
  void test() {
    assertThat(VAL_MSG_NOT_NULL).isEqualTo("must not be null");
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜