`

Spring 利用MessageSource实现国际化

阅读更多

Spring 利用MessageSource实现国际化

spring中ResourceBundleMessageSource与ReloadableResourceBundleMessageSource查找资源的区别:

1.ResourceBundleMessageSource在xml配置中无法指定编码:

     <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

     <property name="basenames">

          <list>

               <value>error</value>

               <value>message</value>

          </list>      

         </property>

     </bean>

而ReloadableResourceBundleMessageSource可以指定编码,譬如:

     <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

        <property name="defaultEncoding" value="gbk" />

        <property name="basename" value="message" />

</bean>

 

2.加载资源文件的方式不同:

 

1).下面看下它们的源代码:

ResourceBundleMessageSource的加载,使用ClassUtils.getDefaultClassLoader()加载器,getDefaultClassLoader的方法代码如下:

public static ClassLoader getDefaultClassLoader()

{

    ClassLoader cl = null;

    try {

      cl = Thread.currentThread().getContextClassLoader();

   }

    catch (Throwable ex) {

      logger.debug("Cannot access thread context ClassLoader - falling back to system class loader", ex);

    }

    if (cl == null)

    {

      cl = ClassUtils.class.getClassLoader();

    }

    return cl;

}

//这种方式也是JVM默认的加载方式,先从当前线程中获取类加载器,如果没有,就获取这个类本身的类加载器

 

2).ReloadableResourceBundleMessageSource默认也使用ClassUtils.getDefaultClassLoader()加载器,它加载资源的方式如下:

public Resource getResource(String location)

{

    Assert.notNull(location, "Location must not be null");

    if (location.startsWith("classpath:")) {

      return new ClassPathResource(location.substring("classpath:".length()), getClassLoader());

    }

    try

    {

      URL url = new URL(location);

      return new UrlResource(url);

    }

    catch (MalformedURLException ex)

    {

      return getResourceByPath(location);

    }

}

 

3). 小结:ResourceBundleMessageSource从classloader中加载资源文件,可以找到,

ReloadableResourceBundleMessageSource加载时,默认使用DefaultResourceLoader,他会先判断资源path是否带有classpath:前缀,如果有,用ClassPathResource去加载资源文件,如果没有试着用文件协议的url去访问,再没有就在contextPath即WEB-INF下查找。

 

 

下面做一个Spring的MessageSource的示例:

 

1.我们单独新建一个spring消息文件beans-message.xml中加如下配置:

   <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

       <property name="basenames">

            <list>

                 <value>error</value>

                 <value>message</value>

            </list>

       </property>

   </bean>

 

2.这段配置假定在你的classpath中有两个资源文件(resource bundle),它们是error, message。通过ResourceBundle,使用JDK中解析消息的标准方式,来处理任何解析消息的请求。出于示例的目的,假定message_zh_CN.properties的资源文件的内容为…

 

msg.common.serverBusy = \u975E\u5E38\u62B1\u6B49,\u7CFB\u7EDF\u5341\u5206\u7E41\u5FD9\!

#非常抱歉,系统十分繁忙!

msg.argument.required={0}\u\u4E\u5FC5\u586B\u9879\!

#{0}是个必填项!

 

3.再写一个测试类:

public class MessageTest {

     public static void main(String[] args) {

         MessageSource resources = new ClassPathXmlApplicationContext("beans-message.xml");

         String message = resources.getMessage("msg.common.serverBusy", null, "Default", null);

         System.out.println(message);

 

         String message1 = resources.getMessage("msg.argument.required", new Object[] { "'联系方式'" }, null, Locale.CHINA);

         System.out.println(message1);

     }

}

结果输入为:

 

非常抱歉,系统十分繁忙!

'联系方式'是个必填项!

 

3.在我们的项目中,MessageSource不会单独使用,通常我们会把它和自己的业务一起使用,这时候我们可以直接用它本身的方法,我们也可以在其中加入我们自己的逻辑:如,自定义的一个消息类:

public class MessageSourceHelper {

     private ResourceBundleMessageSource messageSource;

     public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {

         String msg = messageSource.getMessage(code, args, defaultMessage, locale);

         return msg != null ? msg.trim() : msg;

     }

    

     public void setMessageSource(ResourceBundleMessageSource messageSource) {

         this.messageSource = messageSource;

     }

}

 

在beans-message.xml中注入:

   <bean id="messageSourceHelper" class="com.myspring.message.MessageSourceHelper">

       <property name="messageSource">

            <ref local="messageSource" />

       </property>

   </bean>

 

4.我们可以在MessageSourceHelper中加入自己的业务,注入依赖后,就可以在其他类中调用MessageSourceHelper中的方法。

 

5.理论简要:ApplicationContext接口扩展了MessageSource接口,因而提供了消息处理的功能(i18n或者国际化)。与HierarchicalMessageSource一起使用,它还能够处理嵌套的消息,这些是Spring提供的处理消息的基本接口。让我们快速浏览一下它所定义的方法:

 

     · String getMessage(String code, Object[] args, String default, Locale loc):用来从MessageSource获取消息的基本方法。如果在指定的locale中没有找到消息,则使用默认的消息。args中的参数将使用标准类库中的MessageFormat来作消息中替换值。

 

     · String getMessage(String code, Object[] args, Locale loc):本质上和上一个方法相同,其区别在:没有指定默认值,如果没找到消息,会抛出一个NoSuchMessageException异常。

 

     · String getMessage(MessageSourceResolvable resolvable, Locale locale):上面方法中所使用的属性都封装到一个MessageSourceResolvable实现中,而本方法可以指定MessageSourceResolvable实现。

 

当一个ApplicationContext被加载时,它会自动在context中查找已定义为MessageSource类型的bean。此bean的名称须为messageSource。如果找到,那么所有对上述方法的调用将被委托给该bean。否则ApplicationContext会在其父类中查找是否含有同名的bean。如果有,就把它作为MessageSource。如果它最终没有找到任何的消息源,一个空的StaticMessageSource将会被实例化,使它能够接受上述方法的调用。

 

Spring目前提供了两个MessageSource的实现:ResourceBundleMessageSource和StaticMessageSource。它们都继承NestingMessageSource以便能够处理嵌套的消息。StaticMessageSource很少被使用,但能以编程的方式向消息源添加消息。ResourceBundleMessageSource会用得更多一些,

 

6. 更多的资料参考spring官方开发手册,很详尽的!

分享到:
评论

相关推荐

    spring messageSource结合ehcache demo

    在本文中,我们将深入探讨如何在Spring框架中利用`messageSource`与Ehcache整合,以实现国际化(i18n)功能并优化提示语句的数据库读取性能。`messageSource`是Spring提供的一种用于处理多语言环境下的消息管理机制,...

    spring国际化项目

    在本项目"spring国际化项目"中,我们将深入探讨如何在Spring环境中实现国际化。 首先,我们需要理解国际化的基本概念。国际化不仅仅是翻译文本,它涉及将应用程序中的所有文化特定元素,如日期格式、货币符号、数字...

    spring mvc 国际化 demo

    3. **使用注解实现国际化** Spring MVC提供了`@MessageSource`注解,可以方便地在控制器方法中获取本地化消息。首先,你需要在控制器类上添加`@Controller`注解,然后在方法上使用`@RequestMapping`注解来处理请求...

    10 扩展之Spring MVC中如何实现国际化i18n慕课专栏1

    Spring MVC的国际化(i18n)是基于Java的国际化机制构建的,它利用Resource Bundle加载对应国家/地区(Locale)的语言资源文件,以便根据用户的语言环境提供相应的信息。Spring MVC通过`ResourceBundleMessageSource...

    spring boot+JPA+easyUI 实现基于浏览器语言的国际化配置

    在这个项目中,我们将探讨如何利用这些技术来实现基于浏览器语言的国际化配置。 1. **Spring Boot的国际化(i18n)支持** Spring Boot通过`MessageSource`接口提供国际化支持。开发者可以创建`messages.properties`...

    Spring中Bean的生命周期 applicationcontext的应用(实现国际化,事件的传递)

    回到我们的项目"SpringJavaProject",它可能包含了一些示例代码,演示了如何配置和使用ApplicationContext来实现国际化和事件传递。例如,我们可能会有一个`MessageSource`配置,用于加载资源束,以及一个或多个`...

    5.3验证框架$国际化

    在Spring框架中,国际化可以通过`MessageSource`接口实现。我们可以配置`ResourceBundleMessageSource`或`ReloadableResourceBundleMessageSource`,将`ValidationMessages`资源文件加载到Spring容器中。这样,...

    基于SpringMVC国际化资源配置方式Demo

    在SpringMVC框架中,实现国际化资源配置是提升用户体验的关键步骤,尤其对于多语言网站来说。这个Demo将向我们展示如何在SpringMVC项目中配置和使用国际化资源文件,以适应不同地区的用户需求。首先,我们需要了解...

    java实现国际化

    Java实现国际化是一个重要的技术主题,尤其对于开发面向全球用户的软件来说。这个过程涉及到将应用程序的文本、日期格式、数字格式等本地化,以便适应不同国家和地区的语言与文化习惯。在Java中,这一功能主要通过...

    springmvc国际化demo

    首先,我们需要了解Spring MVC中实现国际化的基本步骤: 1. **配置资源文件**: - 在项目中创建`src/main/resources`目录下的`messages.properties`(默认语言,如英语)和`messages_zh_CN.properties`(中文)等...

    web项目国际化

    在Web项目中,实现国际化能够让网站服务全球用户,提供多语言支持,提升用户体验。 在Java Web开发中,我们经常使用Spring框架来处理国际化。Spring提供了强大的支持,包括`ResourceBundle`和`MessageSource`接口,...

    SpringMVC-10 国际化

    本教程将详细讲解如何利用SpringMVC实现国际化(Internationalization,简称i18n),以提供多语言支持。 一、国际化基本概念 国际化是一种设计和开发软件的方式,使其能够适应不同的语言和文化环境。这通常涉及到...

    spring2.0升级到spring3.0.5的开发包

    8. **国际化支持**:Spring 3.0的MessageSource接口提供了更好的国际化支持,可以更方便地处理多语言环境。 9. **测试框架增强**:Spring 3.0的测试支持更加完善,包括对Mockito等第三方库的集成,使得单元测试和...

    spring-spring-framework-4.3.24.RELEASE.zip

    8. **国际化和本地化**:Spring通过MessageSource接口处理多语言环境下的文本消息。在`org.springframework.context.support`包中,我们可以找到实现这一功能的类。 9. **任务调度**:Spring的Task模块提供了异步...

    springMVC国际化

    在Spring MVC中实现国际化,我们可以利用Spring提供的`MessageSource`接口和资源文件来实现。 首先,我们需要创建资源文件,这些文件通常以`.properties`格式存储,例如`messages.properties`和`messages_zh_...

    异常信息国际化

    首先,`I18N.java` 文件可能是一个Java类,用于实现国际化的功能。在Java中,我们可以使用`java.util.ResourceBundle` 类来管理不同语言的资源文件。这些资源文件通常以`.properties` 格式存储,其中包含了键值对,...

    Spring2.5-中文参考手册chm

    Spring 2.5提供了对多语言环境的支持,允许开发者通过ResourceBundle和MessageSource接口来实现应用程序的国际化和本地化。 **JSR-303验证支持** Spring 2.5集成了JSR-303 Bean Validation规范,提供了对JavaBeans...

    Java 国际化操作

    Java通过使用Resource Bundle和Locale对象来实现国际化。 1. **Locale对象**:在Java中,`java.util.Locale`类代表了一个特定的语言环境,它包含了语言、国家和地区的信息。例如,`new Locale("en", "US")`表示英语...

Global site tag (gtag.js) - Google Analytics