Spring 学习小记(十七)

67 篇文章 0 订阅
Spring MVC 国际化
 
本小记学习目标
  1. Java国际化思想介绍
  2. Spring MVC的国际化介绍
  3. 自定义切换语言
 
一、Java国际化的思想介绍
把程序中的信息放在资源文件中,程序根据语言信息来读取相应的国际化资源文件。
资源文件是以key-value对的形式存在,资源文件中的key是保持不变的,但是value会随不同的语言环境而有所变化。
 
Java程序的国际化主要由两个类来支持
java.util.Locale:它提供本地信息,一般把它称为语言环境。对于不同的语言,不同的地区使用不同的Locale对象来表示。
java.util.ResourceBundle:这个类称为资源包,包含了特定于语言环境的的资源对象。当程序需要一个特定于语言环境的资源时,程序可以从适合当前用户语言环境的资源包中加载它,这样可以编写独立于语言环境的程序代码,对于特定语言环境的信息通过资源包来提供即可。
 
从上面可以看到,需要实现Java程序的国际化,必须事先提供程序需要的资源文件,资源文件则是同由多个key-value对组成,其中key是在程序中需要使用的,value则是在界面中呈现的内容。
 
资源文件的命名可以有如下三种形式:
  1. baseName.properties
  2. baseName_language.properties
  3. basName_language_country.properties
baseName是资源文件的基本名称,是由用户自行定义的,但是language和country则必须是Java所支持定义的语言和地区代码
如:中国大陆则定义名称为:baseName_zh_CN.properties
注意:Java中的资源文件只支持ISO-8859-1编码的格式字符,可以使用Java命令native2ascii.exe解决资源文件的中文乱码问题
 
java.util.Locale常用构造方法:
public Locale(String language);
public Locale(String language,String country);
language:语言代码,由两个小写的字母组成
country:国家代码,由两个大写的字母组成
如果需要获取Java可以支持的language和country则可以通过getAvailableLocales方法获取,它会返回一个Locale的数组
新增一个Java程序,通过如下方法进行遍历获取Java所支持的语言及国家信息
package com.xiaoxie.locale.test;
import java.util.Locale;
public class Test {
       public static void main(String[] args) {
             //返回Java支持的语言及国家代码
            Locale[] availableLocales = Locale. getAvailableLocales();
             //遍历数组
             for (Locale locale : availableLocales) {
                  System. out.print( "国家:");
                  System. out.print( locale.getDisplayCountry() + " = " + locale.getCountry());
                  System. out.print( "\t语言:");
                  System. out.println( locale.getDisplayLanguage() + " = " + locale.getLanguage());
            }
      }
}
现在需要进行国际化处理,则需要把工呈现的信息定义为资源文件
新增两个资源文件:messageResource_zh_CN.properties、messageResource_en_US.properties
messageResource_zh_CN.properties
hello= \u6211\u5411\u4E0D\u540C\u56FD\u5BB6\u7684\u4EBA\u95EE\u597D\uFF01
注意:上面的实际是对中文的unicode编码,Eclipse中会自动处理,直接把hello对应的中文复制进去即可这个转unicode的会自动进行
messageResource_en_US.properties
hello= I want to say hello!
修改测试类及测试方法
package com.xiaoxie.locale.test;
import java.util.Locale;
import java.util.ResourceBundle;
public class Test {
       public static void main(String[] args) {
             //printLocales();
             //取得系统默认的语言环境
            Locale defaultLocale = Locale. getDefault();
             //加载资源文件
            ResourceBundle rb = ResourceBundle. getBundle( "messageResource", defaultLocale);
             //打印从资源文件中获取的信息
            System. out.println( rb.getString( "hello"));
      }
      
       /*打印所有的Locale信息*/
       private static void printLocales() {
             //返回Java支持的语言及国家代码
            Locale[] availableLocales = Locale. getAvailableLocales();
             //遍历数组
             for (Locale locale : availableLocales) {
                  System. out.print( "国家:");
                  System. out.print( locale.getDisplayCountry() + " = " + locale.getCountry());
                  System. out.print( "\t语言:");
                  System. out.println( locale.getDisplayLanguage() + " = " + locale.getLanguage());
            }
      }
}
注意:ReourceBundle.getBundle方法中的“messageResource”是一个baseName,当程序找不到对应的资源文件时,它会做如下的资源文件顺序的检索:messageResource_zh_CN.properties、messageResource_zh.properties、messageResource.properties
如果经过上面的检索还找不到则会报出异常
 
带占位符的国际化消息
在资源文件中对于消息的文本可以带有占位符,如
hello=My name is {0}
这里的{0}就是一个占位符,它可以在呈现消息的时候动态地被替换。这里占位符中的数字可以是0~9,也就是说一个消息中可以最多设置10个占位符
 
如何动态地替占位符?
可以使用java.text.MessageFormat类,这个类有一个静态的方法format,可以用来格式化带参数的文本
public static String format(String pattern,Object ... args)
这里pattern是一个带有占位符的字符串(可能理解为就是一个资源文件中需要呈现的文本,这个文本中带有占位符)
消息文本中的占位符会按照顺序从第二个参数开始依次地被替
我们在前面实例中messageResource_zh_CN.properties中添加一个info的资源展示信息
info= \u4F60\u597D\u6211\u53EB {0} ,\u6211\u6765\u81EA\u4E8E {1} \u3002
对main方法中填加一行代码以展示这个info资源对应的信息(这个资源中存在两个占位符),需要对获取的的信息调用MessageFormat.format方法进行格式化
//带占位符信息的展示
System. out .println(MessageFormat. format ( rb .getString( "info" ), "小谢" , "湖南" ));
 
二、Spring MVC国际化介绍
Spring MVC的国际化实现是建立在Java国际化基础之上的,它的底层国际化与Java国际化是一致的。只是它把Java国际化的功能进行了封装和简化。
要实现国际化有两个必要的条件
  1. 把文本信息放到资源属性文件中
  2. 选择和读取正确位置资源文件
Spring MVC如何加载资源属性文件
在Java国际化中我们看到在加载资源文件时的方法如下:
//加载资源文件
ResourceBundle rb = ResourceBundle. getBundle( "messageResource", defaultLocale);
但是Spring MVC不可以直接使用ResourceBundle加载资源属性文件,而是配置bean来通知Spring MVC 框架资源属性文件放到哪里
示例如下:
< bean class= "org.springframework.context.support.ResourceBundleMessageSource" id= "messageSource" >
       <!-- 资源文件 -->
       < property name= " basename" value= "classPath:messages" />
</ bean >
注意:其中classpath表示是classpath路径,也可以指定在其它的路下
如果有一组属性文件则可以把beanname替换为beannames
< property name= " basenames" >
    <list> classPath:messages </list>
     <list> classPath:messages1 </list>
</property>
Spring MVC中可以使用语言区域解析器bean选择语言区域,这个bean有三个常见的实现类
  1. AcceptHeaderLocaleResolver
  2. SessionLocaleResolver
  3. CookieLocaleResolver
AcceptHeaderLocaleResolver: 根据浏览器Http Header中的accept-language域设定
SessionLocaleResolver:根据用户本次会话Session中的语言设定(比如:用户在进入首页后选择了语言,则在这次会话周期内都会使用这种语言设定)
CookieLocaleResolver:根据Cookie判断用户的语言设定,Cookie中保存了用户上一次的语言设定参数
例如使用SessionLocaleResolver实现则在配置文件中需要做两个配置
第一个,指定语言区域解析器的bean
< bean id= "localeResolver" class= "org.springframework.web.servlet.i18n.SessionLocaleResolver" />
第二个,配置拦截器(对于使用Cookie和Session的语言配置bean必须要配置这个拦截器)
< mvc:interceptors >
       <!-- 国际化操作拦截器如果采用基于(Session/Cookie则必须配置) -->
       < bean class= "org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</ mvc:interceptors >
JSP页面显示国际化信息方式:使用message标签
当要使用message标签需要在jsp页面中添加taglib指令做好标签声明
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
message标签的常用属性:
  1. code:获得国际化消息的key
  2. arguments:代表替换消息中的占位符参,如:<spring:message code="info" arguments="1,2"/>(这其中的1和2分别会替换消息占位符{0},{1})
  3. argumentSeparator:用来分隔参数的字符,它是有默认值的,默认值为逗号
  4. text:当code这个key值不存在,或者是无法获取到消息时则显示text指定的文本信息
 
三、自己定义切换语言的实现实例
1.创建一个maven的war工程,在pom.xml中添加如下依赖
< dependencies >
             <!-- context -->
             < dependency >
                   < groupId >org.springframework </ groupId >
                   < artifactId >spring-context </ artifactId >
                   < version >5.0.2.RELEASE </ version >
             </ dependency >
          <!-- Spring MVC -->
          < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring- webmvc </ artifactId >
             < version >5.0.2.RELEASE </ version >
          </ dependency >
         
          <!-- Spring web -->
          < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring-web </ artifactId >
             < version >5.0.2.RELEASE </ version >
             </ dependency >
         
          <!-- commons-logging -->
          < dependency >
             < groupId >commons-logging </ groupId >
             < artifactId >commons-logging </ artifactId >
             < version >1.2 </ version >
          </ dependency >
         
          <!-- spring- aop -->
          < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring- aop </ artifactId >
             < version >5.0.2.RELEASE </ version >
          </ dependency >
         
             < dependency >
             < groupId >javax.servlet </ groupId >
             < artifactId > jstl </ artifactId >
             < version >1.2 </ version >
             </ dependency >
       </ dependencies >
2.新增国际化资源文件:message_zh_CN.properties、message_en_US.properties
message_zh_CN.properties
name= \u59D3\u540D
submit= \u63D0\u4EA4
welcome= \u6B22\u8FCE
info= \u6211\u7684\u540D\u5B57\u662F {0}
language.cn= Chinese
language.en= English
message_en_US.properties
name= name
submit= submit
welcome= welcome
info= my name is {0}
language.cn= Chinese
language.en= English
3.新增jsp文件first.jsp、home.jsp(在/WEB-INF/jsp下)
first.jsp
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %>
<%@ taglib prefix= "spring" uri= "http://www.springframework.org/tags" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >First </ title >
</ head >
< body >
       < a href= "${pageContext.request.contextPath } /i18n?locale=zh_CN" >
             < spring:message code= "language.cn" />
       </ a >
       < a href= "${pageContext.request.contextPath } /i18n?locale=en_US" >
             < spring:message code= "language.en" />
       </ a >
      
       < form action= "${pageContext.request.contextPath } /submit" method= "post" >
             < spring:message code= "name" />: < input type= "text" name= "name" />
             < input type= "submit" value= " < spring:message code= "submit" /> " >
       </ form >
</ body >
</ html >
home.jsp
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %>
<%@ taglib prefix= "spring" uri= "http://www.springframework.org/tags" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >home </ title >
</ head >
< body >
       < spring:message code= "welcome" />, < spring:message code= "info" arguments= "${name } " />
</ body >
</ html >
3.新增controller实现类:I18Controller、HomeController
I18Controller
package com.xiaoxie.controller;
import java.util.Locale;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class I18nController {
       @RequestMapping( "/i18n")
       public String first(Locale locale) {
             return "first";
      }
}
HomeController
package com.xiaoxie.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
       @RequestMapping( "/first")
       public String first() {
             return "first";
      }
      
       @RequestMapping( "/submit")
       public String submit(String name,Model model) {
             model.addAttribute( "name", name);
             return "home";
      }
}
    1、访问/first时经过拦截器会进入到first.jsp页面
    2、当提交信息时会带上提交过来的参数进入到home.jsp页面
    3、当点击first.jsp中的资源链接,会调用/i18n,并且会带上指定的locale参数
 
4.新增spring的配置文件springmvc.xml
<? xml version= "1.0" encoding= "UTF-8" ?>
       xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context= "http://www.springframework.org/schema/context"
       xmlns:mvc= "http://www.springframework.org/schema/mvc"
       < context:component-scan base-package= "com.xiaoxie.controller" />
       <!-- 配置视图解析器 -->
       < bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" id= "internalResourceViewResolver" >
             <!-- 前缀 -->
             < property name= " prefix" value= "/WEB-INF/jsp/" />
             <!-- 后缀 -->
             < property name= " suffix" value= ".jsp" />
       </ bean >
       <!-- 加载国际化资源文件 -->
    < bean id= "messageSource" class= "org.springframework.context.support.ResourceBundleMessageSource" >
        < property name= " basename" value= "message" />
    </ bean >
    < mvc:interceptors >
       <!-- 国际化操作拦截器如果采用基于(Session/Cookie则必须配置) -->
       < bean class= "org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
    </ mvc:interceptors >
    <!-- 存储区域设置信息 -->
    < bean id= "localeResolver" class= "org.springframework.web.servlet.i18n.SessionLocaleResolver" >
       < property name= " defaultLocale" value= "zh_CN" />
    </ bean >
      
</ beans >
5.配置web.xml文件
<? xml version= "1.0" encoding= "UTF-8" ?>
<!-- 前端核心 servlet 的配置(DispatcherServlet) -->
       < servlet >
             < servlet-name >springDispatcherServlet </ servlet-name >
             < servlet-class >org.springframework.web.servlet.DispatcherServlet </ servlet-class >
             < init-param >
                   < param-name >contextConfigLocation </ param-name >
                   < param-value >classpath:springmvc.xml </ param-value >
             </ init-param >
             < load-on-startup >1 </ load-on-startup >
       </ servlet >
       <!-- Map all requests to the DispatcherServlet for handling -->
       < servlet-mapping >
             < servlet-name >springDispatcherServlet </ servlet-name >
             < url-pattern >/ </ url-pattern >
       </ servlet-mapping >
      
       <!-- 配置解决 psot 请求中文乱码问题 -->
       < filter >
             < filter-name >CharacterEncodingFilter </ filter-name >
             < filter-class >org.springframework.web.filter.CharacterEncodingFilter </ filter-class >
             < init-param >
                   < param-name >encoding </ param-name >
                   < param-value > utf-8 </ param-value >
             </ init-param >
             < init-param >
                   < param-name >forceEncoding </ param-name >
                   < param-value >true </ param-value >
             </ init-param >
       </ filter >
       < filter-mapping >
             < filter-name >CharacterEncodingFilter </ filter-name >
             < url-pattern >/* </ url-pattern >
       </ filter-mapping >
</ web-app >
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@PostConstruct是Java中的一个注解,用于修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。该方法会在构造函数之后执行,init()方法之前执行。\[1\] 在给定的代码示例中,@PostConstruct注解被用于SomeBean类的init()方法上。这意味着在SomeBean对象被创建后,init()方法会被自动调用。\[2\] 在Spring框架中,可以使用@Component注解来标记一个类,并通过配置<context:component-scan>指定要扫描的包。当Spring容器扫描到被@Component注解标记的类时,会将其纳入管理,相当于配置了一个bean属性。默认情况下,被@Component注解标记的类的id会根据类名生成,首字母小写。如果需要指定id,可以在@Component注解中使用双引号指定。\[3\] #### 引用[.reference_title] - *1* [@PostContruct注解的使用](https://blog.csdn.net/W_317/article/details/116270542)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spring学习小记1—SSM—Spring](https://blog.csdn.net/Mackyhuang/article/details/82431863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值