You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用属性文件与资源束配置Spring Validator及JSP错误消息

Avoiding Resource Bundles for Spring Validator Localized Error Messages

Great question! The org.springframework.context.NoSuchMessageException you're hitting is because Spring's default validation system expects to resolve error message codes from resource bundles (like messages.properties) by default. If you want to skip property files entirely, here are some solid, localized alternatives:

1. Use Spring's StaticMessageSource (Simple Hardcoded Localized Messages)

Spring provides a built-in StaticMessageSource that lets you register localized messages directly in code—no property files required. It's perfect if your error messages are static and don't need frequent updates.

Example Configuration (Java Config):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.StaticMessageSource;
import java.util.Locale;

@Configuration
public class ValidationConfig {

    @Bean
    public StaticMessageSource messageSource() {
        StaticMessageSource messageSource = new StaticMessageSource();
        
        // Register English (en_IN) message
        messageSource.addMessage(
            "please enter user firstname.keyUserRegistration.firstName",
            new Locale("en", "IN"),
            "Please enter your first name"
        );
        
        // Add other locales as needed (e.g., Hindi)
        messageSource.addMessage(
            "please enter user firstname.keyUserRegistration.firstName",
            new Locale("hi", "IN"),
            "कृपया अपना पहला नाम दर्ज करें"
        );
        
        return messageSource;
    }
}

This replaces Spring's default message source, so when your validator uses rejectValue with the message code, it will pull the localized message directly from this in-memory source instead of looking for property files.

2. Build a Custom MessageSource for Dynamic Localized Messages

If you need to pull localized messages from a database, CMS, or another dynamic source, create a custom implementation of MessageSource by extending AbstractMessageSource. This gives you full control over where messages are stored and retrieved.

Example Custom Message Source:

import org.springframework.context.support.AbstractMessageSource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class DatabaseBackedMessageSource extends AbstractMessageSource {

    // Simulate a database lookup - replace with actual DB calls in production
    private final Map<Locale, Map<String, String>> localizedMessages = new HashMap<>();

    public DatabaseBackedMessageSource() {
        // Initialize English messages
        Map<String, String> enInMessages = new HashMap<>();
        enInMessages.put("please enter user firstname.keyUserRegistration.firstName", "Please enter your first name");
        localizedMessages.put(new Locale("en", "IN"), enInMessages);
        
        // Initialize Hindi messages
        Map<String, String> hiInMessages = new HashMap<>();
        hiInMessages.put("please enter user firstname.keyUserRegistration.firstName", "कृपया अपना पहला नाम दर्ज करें");
        localizedMessages.put(new Locale("hi", "IN"), hiInMessages);
    }

    @Override
    protected MessageFormat resolveCodeInternal(String code, Locale locale) {
        // Fallback to en_IN if the requested locale isn't available
        Map<String, String> messages = localizedMessages.getOrDefault(locale, localizedMessages.get(new Locale("en", "IN")));
        String message = messages.get(code);
        
        return message != null ? new MessageFormat(message, locale) : null;
    }
}

Register It in Spring:

@Bean
public MessageSource messageSource() {
    return new DatabaseBackedMessageSource();
}

This approach is ideal if you need to update messages without redeploying your app, or if you already have localized content stored in a database.

3. Directly Inject Localized Messages in Your Validator

If you want to skip the message source entirely, you can handle localization directly in your validator by fetching the current request's locale and returning the appropriate message. This avoids any message code resolution altogether.

Example Validator:

import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.util.StringUtils;
import java.util.Locale;

public class UserRegistrationValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return UserRegistration.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        UserRegistration user = (UserRegistration) target;
        Locale currentLocale = LocaleContextHolder.getLocale();

        if (StringUtils.isEmpty(user.getFirstName())) {
            String errorMessage;
            
            // Determine message based on current locale
            if (new Locale("hi", "IN").equals(currentLocale)) {
                errorMessage = "कृपया अपना पहला नाम दर्ज करें";
            } else {
                errorMessage = "Please enter your first name";
            }
            
            // Pass null as the message code to skip resource bundle lookup
            errors.rejectValue("firstName", null, errorMessage);
        }
    }
}

Note the null in rejectValue—this tells Spring not to try resolving a message code, and to use the provided message directly.

Which Option is Best?

  • Use StaticMessageSource for simple, static localized messages (low overhead, easy to set up).
  • Use a custom MessageSource if you need dynamic, updatable messages (database/CMS integration).
  • Use direct validator messages only if you have a small number of validation rules and don't want to maintain a message source (though this couples localization logic to your validator, which isn't ideal for large apps).

All of these approaches will eliminate the NoSuchMessageException since they bypass Spring's default resource bundle lookup.

内容的提问来源于stack exchange,提问作者vikas patidar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:37:07