`
cloudtech
  • 浏览: 4640756 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

Using resource bundle for validation messages in Spring

 
阅读更多
What i am trying to do is
1. putting up the messages file in WEB-INF/i18/validationMessages_en.properties and trying to validate the messages on login.

The dispatcher-servlet.xml contains
  1. <context:component-scanbase-package="com.practise.controller"/>
  2. <beanid="userValidator"class="com.practise.validator.UserValidator">
  3. </bean>
  4. <beanclass="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
  5. <beanclass="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
  6. <beanid="viewResolver"class="org.springframework.web.servlet.view.UrlBasedViewResolver">
  7. <propertyname="viewClass"value="org.springframework.web.servlet.view.JstlView"/>
  8. <propertyname="prefix"value="/WEB-INF/jsp/"/>
  9. <propertyname="suffix"value=".jsp"/>
  10. </bean>
  11. <beanid="messageSource"class="org.springframework.context.support.ResourceBundleMessageSource">
  12. <propertyname="basenames"value="/WEB-INF/i18n/validationMessages_en">
  13. </property>
  14. </bean>


  1. @RequestMapping(value="/login",method=RequestMethod.GET)
  2. publicModelAndViewauthenticateUser(HttpServletRequestrequest,
  3. HttpServletResponseresponse,
  4. @ModelAttribute("loginbean")LoginBeanloginbean,
  5. BindingResultresult){
  6. ModelMapobjModel=newModelMap();
  7. userValidator.validate(loginbean,result);
  8. objModel.addAttribute("loginbean",loginbean);
  9. if(result.hasErrors()){
  10. returnnewModelAndView("home",objModel);
  11. }
  12. returnnewModelAndView("practise",objModel);
  13. }


the valdation class

  1. publicclassUserValidatorimplementsValidator{
  2. @Override
  3. publicbooleansupports(ClassaClass){
  4. returnLoginBean.class.equals(aClass);
  5. }
  6. @Override
  7. publicvoidvalidate(Objectarg0,Errorserrors){
  8. ValidationUtils.rejectIfEmptyOrWhitespace(errors,"username","username.required");
  9. ValidationUtils.rejectIfEmptyOrWhitespace(errors,"password","password.required");
  10. }



validationMessages.properties
  1. username.required=UserNameisarequiredfield.
  2. password.required=Passwordisarequiredfield.


below is the error console
org.springframework.context.NoSuchMessageException: No message found under code 'username.required' for locale 'en_US'.
at org.springframework.context.support.AbstractMessageSource.getMessage(AbstractMessageSource.java:161)
at org.springframework.context.support.AbstractApplicationContext.getMessage(AbstractApplicationContext.java:1196)
at org.springframework.web.servlet.support.RequestContext.getMessage(RequestContext.java:553)
at org.springframework.web.servlet.support.BindStatus.initErrorMessages(BindStatus.java:177)
at org.springframework.web.servlet.support.BindStatus.getErrorMessages(BindStatus.java:273)
at org.springframework.web.servlet.tags.form.ErrorsTag.exposeAttributes(ErrorsTag.java:173)
at org.springframework.web.servlet.tags.form.AbstractHtmlElementBodyTag.writeTagContent(AbstractHtmlElementBodyTag.java:48)
at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
at org.apache.jsp.WEB_002dINF.jsp.home_jsp._jspService(home_jsp.java:112)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)

______________________________________________________________
But when i put my properties file under src folder and change my dispatcher-servelet as
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="validationMessages_en">
</property>
</bean

all seems to work fine.

What may be the problem if i use i18n and put my properties file under this folder


Thanks Jaspreet ----- Nothing is permanent

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

I would like to mimic the Grails way of resolving i18n messages.

In WEB-INF/i18n/ I have the following directories:

admin/messages_EN.properties

admin/messages_FR.properties

website/messages_EN.properties

website/messages_FR.properties

please ignore the language endings ( EN and FR ) in this example

in my xml configuration I currently have:

<!-- Register the welcome.properties -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
 <property name="defaultEncoding" value="utf-8" />
 <property name="basename" value="/WEB-INF/i18n/" />
</bean>

What I am looking for here, is a way to tell Spring to look for .properties files under i18n but without explicitly telling it what each subdirectory is. That is without a list of basenames that points to /WEB-INF/i18n/admin/ and /WEB-INF/i18n/website/

I want the WEB-INF/i18n/ directory to be dynamic, and that bundles ( directories ) can be created without having to remodify the xml configuration file.

I am not trying to solve this particular example with admin and website sub directories

Is this possible?

Thanks!

share|improve this question

54% accept rate
You'll probably have to extend ReloadableResourceBundleMessageSource to introduce some sort of discover property that causes the message source to search the basename directory, instead of loading files directly.Paul Grime Jun 20 at 10:51
@PaulGrime I have implemented something based on your suggestion and edited my question to include the suggested implementation. Something along these lines should work right? Missing something? Thanks!Hamidam Jun 20 at 15:17
feedback
up vote 0 down vote accepted

Here is the solution:

package com.mypackage.core.src;

import java.io.File;
import java.util.ArrayList;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

public class UnderDirectoryReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource {

  @Autowired
  ServletContext servletContext;

  public void setWorkingDirectory(String directoryPath) {
    File rootDir = new File( servletContext.getRealPath(directoryPath) );
    ArrayList<String> baseNames = new ArrayList<String>();
    iterateScanDirectoryAndAddBaseNames(baseNames, rootDir);
    setBasenames(baseNames.toArray(new String[baseNames.size()]));
  }

  private void iterateScanDirectoryAndAddBaseNames(ArrayList<String> baseNames, File directory) {
    File[] files = directory.listFiles();

    for (File file : files) {
      if (file.isDirectory()) {
        iterateScanDirectoryAndAddBaseNames(baseNames, file);
      } else {
        if (file.getName().endsWith(".properties")) {
          String filePath = file.getAbsolutePath().replaceAll("\\\\", "/").replaceAll(".properties$", "");
          filePath = filePath.substring(filePath.indexOf("/WEB-INF/"), filePath.length());
          baseNames.add(filePath);
          System.out.println("Added file to baseNames: " + filePath);
        }
      }
    }
  }

}

XML config:

<bean id="messageSource" class="com.mypackage.core.src.UnderDirectoryReloadableResourceBundleMessageSource">
 <property name="defaultEncoding" value="utf-8" />
 <property name="workingDirectory" value="/WEB-INF/webspring/i18n" />
 <property name="cacheSeconds" value="3" />
 <property name="fallbackToSystemLocale" value="false" />
</bean>

Enjoy!





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics