• 国际化 [ Internationalization ] -- 缩写为 I18N -- 取开头和结尾两个字母,中间有 18 个字母
• 种类:
○ 硬编码国际化 [ 静态国际化 ] -- 程序中不变的代码 [ jsp 页面中的静态代码 ]
§ 硬编码国际化实例 -- 依据 locale 信息
§ 硬编码国际化实例 -- 自动切换
○ 动态信息国际化 -- 程序中动态天生的代码 -- 提示信息 / 非常信息
§ 动态信息国际化
§ 动态信息国际化 -- 编程式非常
• 国际化文件组成:
○ baseName +[ 基名 + _措辞名_国家名.properties ]
如:MessageResources_en_US.properties 措辞小写,国家大写
○ baseName [ 基名.properties ]
§ 如:MessageResources.properties -- 默认国际化资源文件,一样平常默认为英文
○ 项目中没有对应措辞的国际化资源文件就利用默认国际化资源文件
○ 默认国际化资源文件:
• 配置:
§ 如果浏览器利用的是法文,在项眼前没有找到法文国际化资源文件 -- 看系统用的措辞 -- 探求系统措辞的国际化资源文件
§ 如果用户系统下所用的措辞在项目中也没有对应的国际化资源文件 -- 利用默认国际化资源文件 [ 一样平常为英文 ]
§ 如果浏览器利用的是法文,在项眼前没有找到法文国际化资源文件 -- 看系统用的措辞 -- 探求系统措辞的国际化资源文件
§ 如果用户系统下所用的措辞在项目中也没有对应的国际化资源文件 -- 利用默认国际化资源文件 [ 一样平常为英文 ]
○ 在 struts-config.xml 主配文件中加 <message-resources> 标签配置信息
<message-resources parameter=\公众res.MessageResources\公众/>
§ 该标签中指定了国际化文件的基名和位置,位置默认在 src 下
§ res -- src 下的一个子目录
○ 将国际化文件放在指定目录下
• 国际化资源文件格式:
○ 作为 properties 文件,为 Map 格式 -- 有 key 和 value
§ 一个项目中各个国际化资源文件的 key 都是同等的,value 根据各国措辞进行相应的变动
○ 中文国际化资源文件:
§ properties 文件中中笔墨符为 ASCII 码 -- struts 框架无法识别中笔墨符
§ 将汉字变为 ASCII 码:
□ native2ascii 指令:
在文件所在目录下进行指令
□ 将源文件直接转换成中文的国际化资源文件:
• 缺陷:代码可读性差
在文件所在目录下进行指令
native2ascii.exe o.properties MessageResources_zh_CN.properties 将源文件的 properties 转换为中文的符合哀求的国际化资源文件
硬编码国际化实例 -- 依据 locale 信息• 利用中文显示:
○ 客户端发出要求:
§ http 协议头上会自动带有 locale 信息 [ 客户端所在的浏览器的措辞信息 ]
§ Tomcat 创建 request 吸收要求字符串 / 要求参数 / cookie / locale / IP 地址
§ Tomcat 取得该用户对应的 session -- 如果是第一次访问,会自动创建 session / 不是第
一次访问,已有 session
§ 从 request 内置工具中取得 locale 信息
§ 将从 request 内置工具中取得的 locale 信息设到 session 中,属性名为
Globals.LOCALE_KEY session.setAttribute(Globals.LOCALE_KEY, locale);
○ 利用国际化资源文件:
§ 针对国际化产生的一个 struts 标签:[ 动态代码,做事器实行 ]
□ <a href=\"大众login1.do\"大众><bean:message key=\"大众user.button.login\公众/></a><br>浏览器显示【登录】
® 先到该用户对应的 session 中取得封装的 locale 信息session.getAttribute( Globals.LOCALE_KEY ); -- 封装了措辞名_国家名
® 到 struts-config.xml 中去找 <message-resources> 标签,从而取得国际化资源文件的基名和位置
◊ 通过 struts 的 Bean-message 标签可以找到国际化资源文件
® 通过标签中的 key,找到国际化资源文件中的 value -- user.button.login=\u767B\u5F55 [ 登录 ]
• 利用英文显示:[ 浏览器的措辞设置为英文 ]
○ 客户端发出要求:
§ http 协议头上会带有 locale 信息 -- 此时 locale 信息中为英文
§ Tomcat 创建 request 工具吸收 locale 信息
§ Tomcat 将从 request 中取得的 locale 信息设到与该用户对应的 session 中
○ 实行 index.jsp 页面:
§ 处理标签:
<a href=\公众login1.do\"大众><bean:message key=\"大众user.button.login\"大众/></a><br>浏览器显示【Login】
□ 此时为英文国际化资源文件
□ 通过标签中的 key,找到国际化资源文件中的 value -- user.button.login=Login
○ 用户通过超链接发出要求,Tomcat 将 locale 信息设到 session 中后将要求提交给 struts: 要求字符串:http://127.0.0.1:8080/test/login1.do
<action path=\"大众/login1\"大众 forward=\"大众/login.jsp\"大众></action>
○ struts 在截取到 path=\"大众/login1\公众 字符串后立即进行 locale 信息的处理: String path = processPath(request, response); processLocale(request, response);
------------------------- processLocale(request, response)
protected void processLocale( HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(); // 取得 session// 判断 session 中是否有 locale 信息,有就不再设置,没有就从 request 中取得信息并设置到 session 中,属性名为 Globals.LOCALE_KEY if (session.getAttribute(Globals.LOCALE_KEY) != null) { return; }Locale locale = request.getLocale();if (locale != null) { session.setAttribute(Globals.LOCALE_KEY, locale); }}
§ 在浏览器上改完措辞要重启浏览器 -- 产生一个新的 session,不然原来的 session 里有原来为中文的 locale 信息,无法变动成功
○ 由于 session 中设置的国际化资源文件为英文 -- 该用户发出任何要求,静态 jsp 页面笔墨都为英文 -- 英文国际化资源文件
硬编码国际化实例 -- 自动切换• 进入首页:
------------------------- index.jsp
<a href=\"大众changelang.do?lang=zh\"大众>中文</a><br>
<a href=\公众changelang.do?lang=en\"大众>英文</a>
• 用户点击超链接发出要求,要求字符串:http://127.0.0.1:8080/test/changelang.do?lang=zh
• struts 截取到 path=\"大众/changelang\"大众:
• struts 处理 locale 信息 -- processLocale():
○ 拿到当前用户对应的 session
○ 看 session 中是否有属性名为 Globals.LOCALE_KEY 的属性值
§ 如果有值就利用原值
§ 如果没有,从 request 中拿到 locale 信息并将取得的 locale 信息设置到 session 中,属
性名为 Globals.LOCALE_KEY
• 在 struts-config.xml 中探求 path=\"大众/changelang\"大众 的 <action> 标签:
<action path=\"大众/changelang\"大众 type=\"大众com.bjsxt.struts.ChangeLanguageAction\公众><forward name=\"大众index\"大众 path=\"大众/index.jsp\公众/></action>
• 通过 type 创建出 Action 工具,并实行 Action 中的 execute() 方法:
------------------------- ChangeLanguageAction.java
String lang = request.getParameter(\"大众lang\公众); // 从用户发出的要求中获取参数名为lang 的参数值Locale currentLocale = Locale.getDefault(); // 给 Locale 一个默认值 -- 默认值为系统措辞
if (\"大众zh\"大众.equals(lang)) {
currentLocale = new Locale(\"大众zh\公众, \"大众CN\"大众); // 如果用户要求中参数名为 lang 的参数值为中文 -- 给 Locale 工具重新赋值为中文国际化资源文件
}else if(\"大众en\公众.equals(lang)) {
currentLocale = new Locale(\公众en\"大众, \"大众US\"大众); // 如果用户要求中参数名为 lang 的参数值为英文 -- 创建一个对应英文国际化资源文件的 locale 工具
}
this.setLocale(request, currentLocale); // this 代表 ChangeLanguageAction,将自己创建好的locale 信息设置到 session 中
return mapping.findForward(\公众index\"大众);
------------------------- setLocale(request, currentLocale)
protected void setLocale(HttpServletRequest request, Locale locale) { HttpSession session = request.getSession();if (locale == null) { locale = Locale.getDefault(); } session.setAttribute(Globals.LOCALE_KEY, locale);}
• 国际化资源文件的动态切换
○ 通过 execute() 方法根据用户超链接选择的参数,重新创建相应的locale 工具并设置到 session 中属性名为 Globals.LOCALE_KEY 的属性值中 -- 可以人为改变先前根据浏览器系统措辞而设置的locale 信息
动态信息国际化• 特点:
○ 国际化资源文件中有动态信息的动态添补位置
• 实例:
§ 如:user.login.success = {0},登录成功
§ {0} -- 动态添补位置
○ 登录界面:
<form action=\"大众login.do\"大众 method=\公众post\"大众><bean:message key=\"大众user.username\"大众/>:<input type=\公众text\"大众 name=\公众username\公众><br><bean:message key=\公众user.password\"大众/>:<input type=\"大众password\公众 name=\"大众password\公众><br><input type=\"大众submit\公众 value=\公众<bean:message key=\"大众user.button.login\公众/>\"大众></form>
○ 通过Bean-message 标签可以拿到国际化资源文件 -- 浏览器显示【User Name】【Password】
○ 用户输入用户名和密码,提交要求,要求字符串:http://127.0.0.1:8080/test/login.do
○ struts 截取到 path=\公众/login\"大众:
○ struts 处理 locale 信息 -- processLocale():
○ 拿到当前用户对应的 session
○ 看 session 中是否有属性名为 Globals.LOCALE_KEY 的属性值
□ 如果有值就利用原值
□ 如果没有,从 request 中拿到 locale 信息并将取得的 locale 信息设置到 session 中,属性名为 Globals.LOCALE_KEY
○ 在 struts-config.xml 中探求 path=\公众/login\公众 的 <action> 标签:
<form-beans>
<form-bean name=\公众loginForm\"大众 type=\公众com.bjsxt.struts.LoginActionForm\"大众/></form-beans><action path=\"大众/login\公众 type=\"大众com.bjsxt.struts.LoginAction\"大众 name=\公众loginForm\"大众 scope=\"大众request\公众validate=\公众false\公众><forward name=\"大众success\"大众 path=\"大众/login_success.jsp\公众/><forward name=\公众error\公众 path=\"大众/login.jsp\公众/></action>
○ 通过 name 找 ActionForm -- 创建出 ActionForm 工具后将表单数据网络到 LoginActionForm: private String username; -- \"大众admin\"大众
private String password; -- \"大众admin\"大众
○ 通过 type 创建出 Action 工具,并实行 Action 中的 execute() 方法:
------------------------- LoginAction.java LoginActionForm laf = (LoginActionForm)form; String username = laf.getUsername();
String password = laf.getPassword();
ActionMessages messages = new ActionMessages(); // 定义一个 ActionMessages
UserManager.getInstance().login(username, password); // 实行业务工具的 login() 方法,顺利实行完后进行以下代码
ActionMessage message = new ActionMessage( \"大众user.login.success\"大众, username ); messages.add(\"大众loginSuccess1\"大众, message);
ActionMessage message1 = new ActionMessage(\公众user.login.success\"大众, username); // 虽然存放的信息一样,但不是同一个工具
messages.add(\公众loginSuccess2\公众, message1); this.saveMessages(request, messages); return mapping.findForward(\"大众success\公众);
□ 即 -- ActionMessage message = new ActionMessage( \公众user.login.success\"大众, new Object[]{username} );
□ 创建国际化文本工具 -- new ActionMessage( \"大众国际化资源文件中的 key\"大众, 要填入到对应的 value 中的添补符中的信息 )
® ActionMessage 的 key 便是国际化资源文件中的 key,value 是一个 Object 数组工具
® Object 数组工具中的数据作为国际化资源文件中的动态添补符
□ 通过 key 找到国际化资源文件中对应的 value -- user.login.success={0},Login Success
□ 用 username 的值去添补国际化资源文件中对应的 value 中的添补符 -- {0}
□ 如果有多个添补位置,利用 Object 数组工具来进行添补 -- 数组中第一个元素添补到 {0},第二个元素添补到 {1} …
® 如:user.login.success={0} login success {1}{2}
® ActionMessage message = new ActionMessage( \"大众user.login.success\"大众, new Object[]{ username, username, username} )
□ 必须将国际化文本工具 ActionMessage 放进 ActionMessages 工具中的一个 Map 凑集 messages 中
® protected HashMap messages = new HashMap(); -- 专门用来存放国际化文本工具
□ ActionMessages 内部有一个 Map 凑集,ActionMessages 不是凑集
□ 此时 messages 里有两个元素:
® key=\"大众loginSuccess1\公众,value 为第一个国际化文本工具 message
® key=\公众loginSuccess2\公众,value 为第二个国际化文本工具 message1
------------------------- saveMessages(request, messages)
request.setAttribute(Globals.MESSAGE_KEY, messages);
® 通报国际化文本
® 将存放了文本工具的ActionMessages 工具放进 request 内置工具中,属性名为 Globals.MESSAGE_KEY
□ 将 ActionMessages 工具设入 request 内置工具中之后,Action 返回给 struts 一个封装了转向路径的 ActionForward 工具
○ struts 解析 ActionForward 工具后转向相应的 jsp 页面 -- login_success.jsp:
<html:messages id=\"大众msg\"大众 message=\公众true\"大众 property=\公众loginSuccess1\"大众><bean:write name=\公众msg\"大众/></html:messages>○ html-messages 标签只能取得 ActionMessages,不能取 ActionMessage○ <html:messages id=\"大众msg\公众 message=\"大众true\公众 property=\公众loginSuccess1\"大众>
□ 先从该用户对应的 session 里找属性名为 Globals.LOCALE_KEY 的属性值 -- 取得国际化资源文件的 locale 信息
□ 到 struts-config.xml 配置文件中找 <message-resources> 标签中找 parameter 属性 -- 取得国际化资源文件的基名和位置
□ 根据 locale 信息和国际化资源文件的基名和位置找到相应的国际化资源文件
□ 从该要求对应的 request 内置工具中取得属性名为 Globals.MESSAGE_KEY 的属性值 -- 取得 ActionMessages 工具
□ 取得 ActionMessages 工具后,到工具中的 messages 凑集中找 key 为 loginSuccess1 的 value -- 取得国际化文本工具 ActionMessage
□ 将 ActionMessage 工具放到 page 内置工具中,属性名为 msg
○ <bean:write name=\"大众msg\公众/>
□ 从 scope 中找 key 为 msg 的属性值 -- 取得 ActionMessage 工具
□ 通过解析 ActionMessage -- 调用 getkey() 方法 -- 取得 ActionMessage 中的 key=\公众user.login.success\"大众
□ 通过取得的 key,到国际化资源文件中找具有相同的 key 的 value -- user.login.success={0},Login Success
□ 通过解析 ActionMessage -- 调用 getValue() 方法 -- 取得 username,并将 username 的值添补到国际化资源文件中的添补位置上
□ 将添补后的信息作为 Bean-write 的标签值返回浏览器显示【admin,Login Success】
--------------------------------------------------------------------------------------------------------------------------------------
<html:messages id=\"大众msg\公众 message=\"大众true\"大众>
<bean:write name=\公众msg\"大众/>
</html:messages>
○ 省略了 property 属性后,处理所有的 ActionMessage
○ <html:messages id=\公众msg\"大众 message=\"大众true\公众>
□ 取得国际化资源文件
□ 从该要求对应的 request 内置工具中取得属性名为 Globals.MESSAGE_KEY 的属性值 -- 取得 ActionMessages 工具
□ 将 ActionMessages 工具内部 Map 凑集 messages 下的所有 value 值都取出 -- 取得 message / message1 两个 ActionMessage 工具
□ 依次将 message / message1 交给 page 内置工具,属性名为 msg
○ <bean:write name=\公众msg\"大众/>
□ 从 scope 中找 key 为 msg 的属性值 -- 取得 ActionMessage 工具 message
□ 通过解析 ActionMessage -- 调用 getkey() 方法 -- 取得 message 中的 key=\公众user.login.success\公众
□ 通过取得的 key,到国际化资源文件中找具有相同的 key 的 value -- user.login.success={0},Login Success
□ 通过解析 message -- 调用 getValue() 方法 -- 取得 username,并将 username 的值添补到国际化资源文件中的添补位置上
□ 再次取得 key 为 msg 的属性值 -- 取得 ActionMessage 工具 message1
□ 通过解析 ActionMessage -- 调用 getkey() 方法 -- 取得 message1 中的 key=\"大众user.login.success\公众
□ 通过取得的 key,到国际化资源文件中找具有相同的 key 的 value -- user.login.success={0},Login Success
□ 通过解析 message1 -- 调用 getValue() 方法 -- 取得 username,并将 username 的值添补到国际化资源文件中的添补位置上
□ 将添补后的信息作为 Bean-write 的标签值返回浏览器显示【admin,Login Success admin,Login Success】
--------------------------------------------------------------------------------------------------------------------------------------
<html:messages id=\公众msg\"大众>
<bean:write name=\"大众msg\公众/>浏览器没有任何显示
</html:messages>
□ message 属性:
® message=\"大众true\公众:见告标签,从 request 中的 Globals.MESSAGE_KEY 中取值
® 不写 message 属性则默认为 false,从 request 中的 Globals.ERROR_KEY 中取值