Saro
Saro

Reputation: 870

<spring:message> tag not working with resource bundles from database

I searched the net a lot for this problem but surprisingly I can't find any similar posts. Here is my code: This is the abstract class which extends AbstractMessageSource

    public abstract class DatabaseMessageSourceBase extends AbstractMessageSource {

private Messages messages;

@Override
protected MessageFormat resolveCode(String code, Locale locale) {
    String msg = messages.getMessage(code, locale);
    return createMessageFormat(msg, locale);

}

@PostConstruct
public void init() {
    this.messages = extractI18NData();
}

abstract protected Messages extractI18NData();

/**
 * 
 * Messages bundle
 */
protected static final class Messages {

    /* <code, <locale, message>> */
    private Map<String, Map<Locale, String>> messages;

    public void addMessage(String code, Locale locale, String msg) {
        if (messages == null)
            messages = new HashMap<String, Map<Locale, String>>();

        Map<Locale, String> data = messages.get(code);
        if (data == null) {
            data = new HashMap<Locale, String>();
            messages.put(code, data);
        }

        data.put(locale, msg);
    }

    public String getMessage(String code, Locale locale) {
        Map<Locale, String> data = messages.get(code);
        return data != null ? data.get(locale) : null;
    }
}

}

And here is the implementation:

@Service("messageSourceVertical")

public class VerticalDatabaseMessageSource extends DatabaseMessageSourceBase {

@Autowired
private LocalizationDao localizationDao;

@Override
protected Messages extractI18NData() {

    List<T_I18N_VERTICAL> tI18NList = localizationDao.getT_I18N_VERTICALData();

    Messages messages = new Messages();
    for(T_I18N_VERTICAL singleResult : tI18NList) {
        messages.addMessage(singleResult.getCode(), new Locale(singleResult.getLocale()), singleResult.getMsg());
    }
    return messages;
}

}

A Simple controller:

@Controller

public class LoginController {

@Autowired
private MessageSource messageSourceVertical;

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
    @RequestParam(value = "error", required = false) String error,
    @RequestParam(value = "logout", required = false) String logout,
    HttpServletRequest request, HttpServletResponse response) {

    ModelAndView model = new ModelAndView();
    if (error != null) {
        model.addObject("error", "Invalid username and password!");
    }

    if (logout != null) {
        model.addObject("msg", "You've been logged out successfully.");
    }
    // this works.
    // model.addObject("msg", messageSourceVertical.getMessage("app.startup.successful", null, new Locale("en")));

    model.setViewName("login");

    return model;

}

}

My html:

<spring:message code="app.startup.successful" />

The application successfully retrieves the message in the controller when I am using the @Autowired messageSourceVertical service. But it fails to work when I am using spring:message. (It throws an exception which says "No message found under code 'app.startup.successful' ...").

Can anyone please help? Thanks.

Upvotes: 0

Views: 1916

Answers (1)

Saro
Saro

Reputation: 870

I found out where the problem was.

When using the spring:message tag in JSP, the application looks for a bean named: "messageSource" which in my case, I had explicitly named my service: "messageSourceVertical".

Changing the @Service("messageSourceVertical") to @Service("messageSource") solved the problem.

Also please note that using Thymeleaf, "protected String getMessageInternal(String code, Object[] args, Locale locale);" method is called and thus has to be overridden to get the proper message.

Upvotes: 1

Related Questions