Java Spring项目国际化(i18n)详细方法与实例

Spring国际化概述

国际化基本规则

国际化信息”也称为“本地化信息”,一般需要两个条件才可以确定一个特定类型的本地化信息,它们分别是“语言类型”和“国家/地区的类型”。如中文本地化信息既有中国大陆地区的中文,又有中国台湾、中国香港地区的中文,还有新加坡地区的中文。Java通过java.util.Locale类表示一个本地化对象,它允许通过语言参数和国家/地区参数创建一个确定的本地化对象。

语言参数使用ISO标准语言代码表示,这些代码是由ISO-639标准定义的,每一种语言由两个小写字母表示。在许多网站上都可以找到这些代码的完整列表,下面的网址是提供了标准语言代码的信息:http://www.loc.gov/standards/iso639-2/php/English_list.php。

国家/地区参数也由标准的ISO国家/地区代码表示,这些代码是由ISO-3166标准定义的,每个国家/地区由两个大写字母表示。用户可以从以下网址查看ISO-3166的标准代码:http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html,部分语言和国家/地区的标准代码如下所示:

语言 简称
简体中文(中国) zh_CN
繁体中文(中国台湾) zh_TW
繁体中文(中国香港) zh_HK
英语(中国香港) en_HK
英语(美国) en_US
英语(英国) en_GB
英语(全球) en_WW
英语(加拿大) en_CA
英语(澳大利亚) en_AU
英语(爱尔兰) en_IE
英语(芬兰) en_FI
芬兰语(芬兰) fi_FI
英语(丹麦) en_DK
丹麦语(丹麦) da_DK
英语(以色列) en_IL
希伯来语(以色列) he_IL
英语(南非) en_ZA
英语(印度) en_IN
英语(挪威) en_NO
英语(新加坡) en_SG
英语(新西兰) en_NZ
英语(印度尼西亚) en_ID
英语(菲律宾) en_PH
英语(泰国) en_TH
英语(马来西亚) en_MY
英语(阿拉伯) en_XA
韩文(韩国) ko_KR
日语(日本) ja_JP
荷兰语(荷兰) nl_NL
荷兰语(比利时) nl_BE
葡萄牙语(葡萄牙) pt_PT
葡萄牙语(巴西) pt_BR
法语(法国) fr_FR
法语(卢森堡) fr_LU
法语(瑞士) fr_CH
法语(比利时) fr_BE
法语(加拿大) fr_CA
西班牙语(拉丁美洲) es_LA
西班牙语(西班牙) es_ES
西班牙语(阿根廷) es_AR
西班牙语(美国) es_US
西班牙语(墨西哥) es_MX
西班牙语(哥伦比亚) es_CO
西班牙语(波多黎各) es_PR
德语(德国) de_DE
德语(奥地利) de_AT
德语(瑞士) de_CH
俄语(俄罗斯) ru_RU
意大利语(意大利) it_IT
希腊语(希腊) el_GR
挪威语(挪威) no_NO
匈牙利语(匈牙利) hu_HU
土耳其语(土耳其) tr_TR
捷克语(捷克共和国) cs_CZ
斯洛文尼亚语 sl_SL
波兰语(波兰) pl_PL
瑞典语(瑞典) sv_SE
西班牙语(智利) es_CL

语言类型判断

1)基于浏览器语言

根据Request Headers中的Accept-language来判断。

2)基于客户端传参

要求客户端第一次(或者每次)传递的自定义参数值来判断,如规定传locale,值为zh-cn、en-us等内容,如果只在第一次传入则local以及timeZone先关信息要存入session或者cookie中,后面的请求语言方式则直接从两者中取,其有效时间与session和cookie设置的生命周期关联。

3)基于默认配置

当获取语言类型时没有找到对应类型时,会使用默认的语言类型。

语言类型保存

<!-- 定义本地化变更拦截器 -->
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<!-- 定义注解URL映射处理器,所有的请求映射关联本地化拦截器,或者也可自定义该拦截器路径映射-->
<bean id="urlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
 <property name="interceptors" ref=" localeChangeInterceptor " />
 <property name="order" value="1"></property>
</bean>

基于url

该种方式需要每次都在请求的url上带上local参数,指定该次需要的语言类型,并且该方式的local解析器需要配置,如下:

<a href="xxx.do?locale=zh_CN" rel="external nofollow" >中文</a>或<a href="xxx.do?locale=en" rel="external nofollow" >英文</a>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>

但在该配置下使用会抛Cannot change HTTP accept header - use a different locale resolution strategy异常,这是因为spring source做了限制,无法对本地的local赋值修改,解决办法如下,新建一个类MyLocaleResolver继承AcceptHeaderLocaleResolver,重写resolveLocale和setLocale方法,并将上面的localeResolver的class指向如下MyLocaleResolver类:

public class MyLocaleResolver extends AcceptHeaderLocaleResolver {
 private Locale myLocal;

public Locale resolveLocale(HttpServletRequest request) {
 return myLocal == null ? request.getLocale() : myLocal;
}

public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
 myLocal = locale;
 }
}

基于session

基于session的状态保存方式只需要在第一次请求的时候指定语言类型,localResolver会将该属性保存到session中,后面的请求直接从session中获取该语言类型,该种方式的localResolver对应的类为SessionLocaleResolver,如下配置:

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>

基于cookie

与session的机制类似,差异在于两者的存储和周期,鉴于安全、大小以及体验等因素的影响,实际使用中使用者更倾向于前者,该种cookie保存方式的localResolver为

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />

文案数据来源

对于语言类型的资源文件,需要开发者对文案进行搜集整理,并翻译成相应的语言确定关键字key,目前大多数情况是将这些信息置于.properties文件中,在使用的时候直接访问获取,当然也可置于数据库中,但频繁的文案获取会影响服务器性能及产品体验,可结合数据字典以及缓存工具使用。

数据库

1)spring 配置方式

<!-- 默认的注解映射的支持 -->
<mvc:annotation-driven validator="validator" conversion-service="conversionService" />
<!-- 资源文件 -->
<bean id="propertiesMessageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
 <property name="basenames">
 <list>
 <value>resource</value>
 <value>validation</value>
 </list>
 </property>
</bean>

<bean id="databaseMessageSource" class="com.obs2.util.MessageResource">
 <property name="parentMessageSource" ref="propertiesMessageSource"/>
</bean>

<bean id="messageInterpolator" class="com.obs2.util.MessageResourceInterpolator">
 <property name="messageResource" ref="databaseMessageSource"/>
</bean>

<!-- 验证器 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
 <property name="messageInterpolator" ref="messageInterpolator"/>
</bean>

这里定义了一个propertiesMessageSource,一个databaseMessageSourcer,和一个messageInterpolator。propertiesMessageSource用于读取properties文件databaseMessageSourcer用于读取数据库的数据配置,其中,有一个属性设置它的父MessageSource为propertiesMessageSource。意思是如果数据库找不到对应的数据,到properties文件当中查找。messageInterpolator是个拦截器。

2)数据库的POJO定义

@Entity
@SuppressWarnings("serial")
@Table(name="resource")

public class Resource implements Serializable {
 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(name="resource_id")
 private long resourceId;

 @Column(name="name", length=50, nullable=false)
 private String name;

 @Column(name="text", length=1000, nullable=false)
 private String text;

 @Column(name="language", length=5, nullable=false)
 private String language;

 public long getResourceId() {
 return resourceId;
 }

 public void setResourceId(long resourceId) {
 this.resourceId = resourceId;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public String getText() {
 return text;
 }

 public void setText(String text) {
 this.text = text;
}

 public String getLanguage() {
 return language;
 }

 public void setLanguage(String language) {
 this.language = language;
 }
}

定义了一张表[resource],字段有:[resource_id]、[name]、[text]、[language]。

3)读取数据库的MessageResource类

/**
* 取得资源数据
* @author Robin
*/
public class MessageResource extends AbstractMessageSource implements ResourceLoaderAware {

 @SuppressWarnings("unused")
 private ResourceLoader resourceLoader;

 @Resource
 private ResourceService resourceService;
 /**
 * Map切分字符
 */
 protected final String MAP_SPLIT_CODE = "|";
 protected final String DB_SPLIT_CODE = "_";

 private final Map<String, String> properties = new HashMap<String, String>();

 public MessageResource() {
 reload();
 }

 public void reload() {
 properties.clear();
 properties.putAll(loadTexts());
 }

 protected Map<String, String> loadTexts() {
 Map<String, String> mapResource = new HashMap<String, String>();
 List<com.obs2.service.bean.Resource> resources = resourceService.findAll();
 for (com.obs2.service.bean.Resource item : resources) {
 String code = item.getName() + MAP_SPLIT_CODE + item.getLanguage();
 mapResource.put(code, item.getText());
 }

 return mapResource;
 }

 private String getText(String code, Locale locale) {
 String localeCode = locale.getLanguage() + DB_SPLIT_CODE + locale.getCountry();
 String key = code + MAP_SPLIT_CODE + localeCode;
 String localeText = properties.get(key);
 String resourceText = code;
 if(localeText != null) {
  resourceText = localeText;
 }else {
  localeCode = Locale.ENGLISH.getLanguage();
  key = code + MAP_SPLIT_CODE + localeCode;
  localeText = properties.get(key);
  if(localeText != null) {
  resourceText = localeText;
  }else {
  try {
   if(getParentMessageSource() != null) {
   resourceText = getParentMessageSource().getMessage(code, null, locale);
   }
  } catch (Exception e) {
   logger.error("Cannot find message with code: " + code);
  }
  }
 }
 return resourceText;
 }

 @Override
 public void setResourceLoader(ResourceLoader resourceLoader) {
 this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
 }

 @Override
 protected MessageFormat resolveCode(String code, Locale locale) {
 String msg = getText(code, locale);
 MessageFormat result = createMessageFormat(msg, locale);
 return result;
 }

 @Override
 protected String resolveCodeWithoutArguments(String code, Locale locale) {
 String result = getText(code, locale);
 return result;
 }
}

主要是重载AbstractMessageSource和ResourceLoaderAware,以实现Spring MVC的MessageSource国际化调用。类中的reload()方法,我把它写到了一个ServletListener当中,让项目启动时,自动加载数据到static的map中。

4)Listener

/**
* 系统启动监听
* @author Robin
*/
public class SystemListener implements ServletContextListener {
/**
* context初始化时激发
*/
@Override
public void contextInitialized(ServletContextEvent e) {
// 取得ServletContext
ServletContext context = e.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils .getWebApplicationContext(context);
// 设置国际化多语言
MessageResource messageSource = applicationContext.getBean(MessageResource.class);
 messageSource.reload();
}

/**
* context删除时激发
*/
@Override
public void contextDestroyed(ServletContextEvent e) {
}

/**
* 创建一个 session时激发
* @param e
*/

public void sessionCreated(HttpSessionEvent e) {
}

/**
* 当一个 session失效时激发
* @param e
*
public void sessionDestroyed(HttpSessionEvent e) {
}
/**
* 设置 context的属性,它将激发attributeReplaced或attributeAdded方法
* @param e
*/
public void setContext(HttpSessionEvent e) {
}

/**
* 增加一个新的属性时激发
* @param e
*/
public void attributeAdded(ServletContextAttributeEvent e) {
}

/**
*删除一个新的属性时激发
* @param e
*/

public void attributeRemoved(ServletContextAttributeEvent e) {

}

/*
* 属性被替代时激发
* @param e
*/
public void attributeReplaced(ServletContextAttributeEvent e) {
}
}

该Listener需要加入到web.xml当中:

<!-- 系统启动监听 -->
<listener>
 <listener-class>com.obs2.util.SystemListener</listener-class>
</listener>

5)Interceptor拦截器

/**
* 拦截Annotation验证信息
* @author Robin
*
*/

public class MessageResourceInterpolator implements MessageInterpolator {
@Resource
private MessageResource messageResource;

public void setMessageResource(MessageResource messageResource) {
 this.messageResource = messageResource;
}

@Override
public String interpolate(String messageTemplate, Context context) {

String messageTemp = null;
 if(messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) {
 messageTemp = messageTemplate.substring(1, messageTemplate.length() - 1);
 }else {
 return messageTemplate;
 }

 String[] params = (String[]) context.getConstraintDescriptor().getAttributes().get("params");
 MessageBuilder builder = new MessageBuilder().code(messageTemp);

 if (params != null) {
 for (String param : params) {
 builder = builder.arg(param);
 }

 }

 String result = builder.build().resolveMessage(messageResource, Locale.ENGLISH).getText();
 return result;

 }

@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {

 String messageTemp = null;
 if(messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) {
 messageTemp = messageTemplate.substring(1, messageTemplate.length() - 1);
 }else {
 return messageTemplate;
 }

 String[] params = (String[]) context.getConstraintDescriptor().getAttributes().get("params");

 MessageBuilder builder = new MessageBuilder().code(messageTemp);
 if (params != null) {
 builder = builder.args(params);
 }

 String result = builder.build().resolveMessage(messageResource, locale).getText();

 return result
 }

}

静态资源

<!-- 资源文件绑定器,文件名称:messages.properties(没有找到时的默认文件), messages_en.properties(英文),messages_zh_CN.properties(中文),等等-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
 <property name="basename" value="config.messages.messages" />
 <property name="defaultEncoding" value="UTF-8"/>
 <property name="basename" value="i18n.messages"/>
 <property name="useCodeAsDefaultMessage" value="true" />
</bean>

文案获取

资源获取接口

MessageSource详解

Spring定义了访问国际化信息的MessageSource接口,并提供了几个易用的实现类。首先来了解一下该接口的几个重要方法:

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

表示国际化资源中的属性名;args用于传递格式化串占位符所用的运行期参数;当在资源找不到对应属性名时,返回defaultMessage参数所指定的默认信息;locale表示本地化对象;

2)String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException

与上面的方法类似,只不过在找不到资源中对应的属性名时,直接抛出NoSuchMessageException异常;

3)String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException

MessageSourceResolvable 将属性名、参数数组以及默认信息封装起来,它的功能和第一个接口方法相同。

MessageSource类结构

MessageSource分别被HierarchicalMessageSource和ApplicationContext接口扩展,这里我们主要看一下HierarchicalMessageSource接口的几个实现类

HierarchicalMessageSource接口添加了两个方法,建立父子层级的MessageSource结构,类似于前面我们所介绍的HierarchicalBeanFactory。该接口的setParentMessageSource (MessageSource parent)方法用于设置父MessageSource,而getParentMessageSource()方法用于返回父MessageSource。

HierarchicalMessageSource接口最重要的两个实现类是ResourceBundleMessageSource和ReloadableResourceBundleMessageSource。它们基于Java的ResourceBundle基础类实现,允许仅通过资源名加载国际化资源。ReloadableResourceBundleMessageSource提供了定时刷新功能,允许在不重启系统的情况下,更新资源的信息。StaticMessageSource主要用于程序测试,它允许通过编程的方式提供国际化信息。而DelegatingMessageSource是为方便操作父MessageSource而提供的代理类。

ResourceBundleMessageSource与ReloadableResourceBundleMessageSource对比

1)通过ResourceBundleMessageSource配置资源

<bean id=" messageSource "
class="org.springframework.context.support.ResourceBundleMessageSource">
 <!--①通过基名指定资源,相对于类根路径-->
 <property name="basenames">
 <list>
 <value>com/baobaotao/i18n/fmt_resource</value>
 </list>
 </property>
 </bean>

2)通过ReloadableResourceBundleMessageSource配置资源

<bean id="messageSource "
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
 <property name="basenames">
 <list>
 <value>com/baobaotao/i18n/fmt_resource</value>
 </list>
 </property>
 <!--①刷新资源文件的周期,以秒为单位-->
 <property name="cacheSeconds" value="5"/>
</bean>

3)对比

两者都是利用资源名通过getMessage()接口就可以加载整套的国际化资源文件,唯一区别在于ReloadableResourceBundleMessageSource可以定时刷新资源文件,以便在应用程序不重启的情况下感知资源文件的变化。很多生产系统都需要长时间持续运行,系统重启会给运行带来很大的负面影响,这时通过该实现类就可以解决国际化信息更新的问题。上面的配置中cacheSeconds属性让ReloadableResourceBundleMessageSource每5秒钟刷新一次资源文件(在真实的应用中,刷新周期不能太短,否则频繁的刷新将带来性能上的负面影响,一般不建议小于30分钟)。cacheSeconds默认值为-1表示永不刷新,此时,该实现类的功能就蜕化为ResourceBundleMessageSource的功能。

页面获取文案

利用Spring标签获取

引入标签库:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

获取文案:

<s:message code="test.app"/>
<spring:message code="main.title" />

利用JSTL标签获取

引入标签库:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%>

获取文案:

<fmt:message key="test.app"/>

Java代码中获取文案

利用MessageSource接口获取

1)自动注入

@Autowired
private MessageSource messageSource;
String s = messageSource.getMessage("SystemError", new Object[]{}, Locale.US);

2)手动bean获取

a. 获取容器

容器已经初始化:

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();

容器没有初始化:

String[] configs = {"com/baobaotao/i18n/beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);

b. 获取bean跟文案

MessageSource ms = (MessageSource) wac.getBean("myResource");
Object[] params = {"John", new GregorianCalendar().getTime()};
String str1 = ms.getMessage("greeting.common",params,Locale.US);

利用Spring容器获取

在前面的MessageSource类图结构中我们发现ApplicationContext实现了MessageSource的接口,也就是说ApplicationContext的实现类本身也是一个MessageSource对象。

将ApplicationContext和MessageSource整合起来, Spring此处的设计人为:在一般情况下,国际化信息资源应该是容器级。我们一般不会将MessageSource作为一个Bean注入到其他的Bean中,相反MessageSource作为容器的基础设施向容器中所有的Bean开放。只要我们考察一下国际化信息的实际消费场所就更能理解Spring这一设计的用意了。国际化信息一般在系统输出信息时使用,如Spring MVC的页面标签,控制器Controller等,不同的模块都可能通过这些组件访问国际化信息,因此Spring就将国际化消息作为容器的公共基础设施对所有组件开放。

既然一般情况下我们不会直接通过引用MessageSource Bean使用国际信息,那如何声明容器级的国际化信息呢? Spring容器启动过程时,在初始化容器的时候通过initMessageSource()方法所执行的工作就是初始化容器中的国际化信息资源,它根据反射机制从BeanDefinitionRegistry中找出名称为“messageSource”且类型为org.springframework.context.MessageSource的Bean,将这个Bean定义的信息资源加载为容器级的国际化信息资源。请看下面的配置:

<!--注册资源Bean,其Bean名称只能为messageSource -->
<bean id="messageSource"
 class="org.springframework.context.support.ResourceBundleMessageSource">
 <property name="basenames">
 <list>
 <value>com/baobaotao/i18n/fmt_resource</value>
 </list>
 </property>
</bean>

然后通过ApplicationContext直接访问国际化信息:

a. 获取容器

容器已经初始化:

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();

容器没有初始化:

String[] configs = {"com/baobaotao/i18n/beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);

b. 获取bean跟文案

Object[] params = {"John", new GregorianCalendar().getTime()};
String str1 = ctx.getMessage("greeting.common",params,Locale.US);

注意事项

1)编码问题

a. 改变properties文件编码为UTF-8/GBK,然而ResourceBundleMessageSource的默认编码defaultEncoding是ISO-8859-1,需要在xml中增加一个相应属性将其改变为你需要的UTF-8/GBK之类。

b. 如果资源文件想统一使用ISO-8859-1格式,可以将原本用UTF-8写好的中文资源文件使用jdk自带的工具native2ascii将UTF-8文件和内容转为ISO-8859-1文件,其中的中文内容会使用16进制unicode编码为\u****格式:

cmd命令:

JAVA_HOME\bin\native2ascii -encoding UTF-8 messages_zh_CN.properties messages_zh_C1N.properties

本文主要讲解了Java Spring项目国际化(i18n)详细方法与实例,更多关于Java Spring项目国际化技巧请查看下面的相关链接

(0)

相关推荐

  • Spring MVC的国际化实现代码

    Spring MVC的国际化是建立在Java国际化的基础上的,其一样是通过提供不同国家的语言环境的消息资源.通过ResourceBundle加载Locale对应的资源文件.再取得该资源文件中指定Key对应的消息. 步骤: 1.给系统加载国际化资源 2.输出国际化.Spring MVC输出国际化消息有两种方式. 在页面上输出国际化消息.需要使用Spring MVC的标签库. 在Controller的处理方法中输出国际化消息.需要使用org.springframework.web.servlet.s

  • 详解SpringMVC学习系列之国际化

    在系列(7)中我们讲了数据的格式化显示,Spring在做格式化展示的时候已经做了国际化处理,那么如何将我们网站的其它内容(如菜单.标题等)做国际化处理呢?这就是本篇要将的内容->国际化. 一.基于浏览器请求的国际化实现: 首先配置我们项目的springservlet-config.xml文件添加的内容如下: <bean id="messageSource" class="org.springframework.context.support.ResourceBun

  • Spring Boot REST国际化的实现代码

    本指南将向您展示如何轻松只需几个简单的步骤即可实现Spring Boot应用的国际化,从而总是在一个地方处理语言环境问题. 我们将讨论如何在现有的Spring Boot项目中添加国际化.当您处理应该为来自不同国家/地区的用户提供不同语言服务的项目时,app国际化的问题变得很常见.比如,你需要向中国用户提供中文回复信息,并向法国用户提供法语信息,那么让我们来看看如何在Spring Boot中实现它. 让我们使用Spring Initializer创建项目 ,这使得项目的创建更容易.选择Web,Se

  • JSP Spring ApplicationContext的国际化支持

    JSP Spring  ApplicationContext的国际化支持 1.ApplicationContext接口继承了MessageResource接口,因此使用ApplicationContext作为spring容器可以使用国际化资源文件. 2.在MessageResource接口中定义了两个主要用于国际化的方法: String getMessage(String param,Object[] args,Locale loc) ; String getMessage(String par

  • Springboot 使用 JSR 303 对 Controller 控制层校验及 Service 服务层 AOP 校验 使用消息资源文件对消息国际化

    导包和配置 导入 JSR 303 的包.hibernate valid 的包 <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.5.Final</version> </dependency> <dependency> <

  • spring security国际化及UserCache的配置和使用

    国际化配置 <!-- 定义上下文返回的消息的国际化 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:config/messages_zh_CN&qu

  • 自己动手在Spring-Boot上加强国际化功能的示例

    前言 公司将项目由Struts2转到Springmvc了,由于公司业务是境外服务,所以对国际化功能需求很高.Struts2自带的国际化功能相对Springmvc来说更加完善,不过spring很大的特性就是可定定制化性强,所以在公司项目移植的到Springmvc的时候增加了其国际化的功能.特此整理记录并且完善了一下. 本文主要实现的功能: 从文件夹中直接加载多个国际化文件后台设置前端页面显示国际化信息的文件利用拦截器和注解自动设置前端页面显示国际化信息的文件 注:本文不详细介绍怎么配置国际化,区域

  • Spring Boot Thymeleaf实现国际化的方法详解

    前言 开发传统Java WEB工程时,我们可以使用JSP页面模板语言,但是在SpringBoot中已经不推荐使用了.SpringBoot支持如下页面模板语言 Thymeleaf FreeMarker Velocity Groovy JSP 上面并没有列举所有SpringBoot支持的页面模板技术.其中Thymeleaf是SpringBoot官方所推荐使用的,下面来谈谈Thymeleaf实现应用国际化方法. ps:当然现在开发基本上是前后端分离了,但是难免需要维护遗留项目或没有条件前后端分离的团队

  • Spring boot+beetl+i18n国际化处理的方法

    国际化(internationalization)是设计和制造容易适应不同区域要求的产品的一种方式.它要求从产品中抽离所有地域语言,国家/地区和文化相关的元素.换言之,应用程序的功能和代码设计考虑在不同地区运行的需要,其代码简化了不同本地版本的生产.开发这样的程序的过程,就称为国际化. Spring boot 搭配慢慢开始火起来的 beetl 模板 配置国际化 首先需要添加WebMvcConfigurer配置 /** * 设置拦截器 */ @Override public void addInt

  • 学习SpringMVC——国际化+上传+下载详解

    一个软件,一个产品,都是一点点开发并完善起来的,功能越来越多,性能越来越强,用户体验越来越好--这每个指标的提高都需要切切实实的做点东西出来,好比,你的这个产品做大了,用的人多了,不仅仅再是上海人用,北京人用,还有印度人用,法国人用等等,可以说这个产品已经走上了国际化的大舞台.当印度的哥们输入url访问产品时,界面上弹出"欢迎您,三哥",估计哥们当场就蒙圈了.而这个时候,国际化就应运而生了. 要做国际化这道菜,真的没有想象中的那么复杂,反而很简单,不信你看-- 1. 注入Resourc

  • 解决Spring国际化文案占位符失效问题的方法

    写在前面:接下来很长一段时间的文章主要会记录一些项目中实际遇到的问题及对应的解决方案,在相应代码分析时会直指问题所在,不会将无关的流程代码贴出,感兴趣的读者可以自行跟踪.同时希望大家能够将心得体会在评论区分享出来,让大家共同进步! 环境或版本:Spring 3.2.3 现象:利用Spring自带的MessageSource来处理国际化文案,us状态下的文案有部分占位符未被替换,cn状态下的正常.文案如下: tms.pallet.order.box.qty=The total palletized

  • 浅谈SpringMVC国际化支持

    这周公司领导希望我对一个项目,出一个国际化的解决方案,研究两个小时,采用了SpringMVC的国际化支持,在此记录下. 原理: 在DispatchServlet中注册 localeResolver(区域解析器) ,并添加 Locale拦截器(LocaleChangeInterceptor) ,来检测请求中的参数和语言环境的改变. 在应用上下文中注册 ResourceBundleMessageSource ,定义国际化文件在程序中的路径和名称. 1. 语言解析器 在SpringMVC中,常用的语言

  • Spring Boot2.X国际化文件编写配置

    这篇文章主要介绍了Spring Boot2.X国际化文件编写配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 国际化文件的编写 messages.properties init project messages_en_US.properties init project messages_zh_CN.properties 页面非连接配置国际化只需要: spring.messages.basename=i18n.login 1: 1.5X版本配

  • Java SpringMVC实现国际化整合案例分析(i18n)

    所谓国际化就是支持多种语言,web应用在不同的浏览环境中可以显示出不同的语言,比如说汉语.英语等.下面我将以具体的实例来举例说明: (1)新建动态Java web项目,并导入几个SpringMVC必需的几个jar包,项目结构图和所需jar包如下: (2)配置web.xml: <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins

  • springboot+thymeleaf国际化之LocaleResolver接口的示例

    springboot中大部分有默认配置所以开发起项目来非常迅速,仅对需求项做单独配置覆盖即可 spring采用的默认区域解析器是AcceptHeaderLocaleResolver,根据request header中的accept-language值来解析locale,并且是不可变的. 那么想要实现国际化,就要使用SessionLocaleResolver或者CookieLocaleResolver.正如类的名字所示,是按session或cookie中储存的locale值来解析locale. 我

  • SpringBoot实现国际化过程详解

    这篇文章主要介绍了SpringBoot实现国际化过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 实现方法:thymeleaf模板引擎加上BootStrap 准备工作: 1.将准备好的Bootstrap模板放在templates下让SpringBoot进行自动配置 SpringBoot自动配置会自动到(idea的shif键连按两下进入全局搜索) 2.Bootstrp的引入(这里是maven以depency的方式引入) <!--引入boot

随机推荐