1、软件国际化
所谓的软件国际化,就是在软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
2、国际化的使用场景
以苹果官网为例,
苹果英文网:https://www.apple.com/
苹果中文网:https://www.apple.com/cn
苹果日本网https://www.apple.com/jp
三个网站基本一样,就是显示的文字稍有不同。
3、固定文本的国际化
例如上面苹果官网的效果,主要是界面显示不同的语言文字但又是固定的文本。所谓固定,就是这些不同文字是事先写好的资源包,根据不同的访问url,给你展示不同的国家的文字。
下面是在不使用Struts2框架时,进行软件国际化的主要步骤。
①、创建一个消息资源包
一个资源包由多个文件组成,这些文件名都有命名规范:`主要文件名_语言代码_国家代码.properties`。
语言代码和国家代码:有iso规定的,比如zh表示中文,CN表示中国
当文件只有主要文件名.properties时,表明它是默认资源包。浏览器会根据不同的语言环境找对应语言环境的资源包
每个资源包的内容都由相同的key和对应语言环境的value组成。
比如:
message_zh_CN.properties
message_en_US.properties
②、读取资源包中的内容
Java提供ResourceBundle类可以读取资源包的国际化配置文件。
在前端JSP中读取国际化配置文件
<%@ page import="java.util.ResourceBundle" %>
<%@ page import="java.util.Locale" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
<html>
<head>
<title>用户注册</title>
</head>
<body>
<%
//通过ResourceBundle类来读取resources包下的message资源文件(资源文件的语言代号、国家代号不需要),
// Locale.US表示读取美国的,Locale.CHINA表示中国
ResourceBundle resourceBundle = ResourceBundle.getBundle("resources.message", Locale.US);
%>
<form action="${pageContext.request.contextPath}/LoginServlet">
<table border="1px">
<tr>
<%--resourceBundle.getString("login.username")表示读取login.username这个key对应的value --%>
<td><%=resourceBundle.getString("login.username")%></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><%=resourceBundle.getString("login.password")%></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="<%=resourceBundle.getString("login.submit")%>">
</td>
</tr>
</table>
</form>
</body>
</html>
浏览器访问效果:
在后端java类中读取国际化配置文件
package cn.hestyle.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;
import java.util.ResourceBundle;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过ResourceBundle类来读取resources包下的message资源文件(资源文件的语言代号、国家代号不需要),
// Locale.US表示读取美国的,Locale.CHINA表示中国
ResourceBundle resourceBundle = ResourceBundle.getBundle("resources.message", Locale.US);
String usernameLable = resourceBundle.getString("login.username");
String passwordLable = resourceBundle.getString("login.password");
String submitLable = resourceBundle.getString("login.submit");
System.out.println("usernameLable:" + usernameLable + "\tpasswordLable:" + passwordLable + "\tsubmitLable:" + submitLable);
}
}
3、Struts提供的国际化
Struts框架中的软件国际化比上面的使用稍微简洁一些,只要在struts.xml中配置了资源包,无需使用java
中的ResourceBundle
类即可直接读取。
第一步、配置资源包
a、配置全局资源包
在src根目录下,新建一个resource的包,并且放置资源文件。
并且在struts.xml文件中进行配置。
b、配置包范围的资源包
资源包名称命名规范:package_语言代码_国家代码.properties(固定的)。以此种命名方式的资源包能被该包及其子包中的动作类访问。
优先级:高于全局消息资源包
包范围的国际化资源包不需要在struts.xml文件中进行配置。
c、配置局部消息资源包
资源包名称命名规范:动作类名称_语言代码_国家代码.properties。以此种命名方式的资源包,只为动作类服务。
优先级最高(就近原则)。
第二步:读取资源包内容
a、在JSP中读取资源包内容
在JSP页面中,通过struts的标签s:text获取国际化内容。(需要导入struts标签库)
可以通过<s:i18n name="资源路径">
指定使用的国际化资源包路径。
<%@ page import="java.util.ResourceBundle" %>
<%@ page import="java.util.Locale" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
<%--导入struts标签库 --%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>用户注册</title>
</head>
<body>
<hr>
全局资源包(默认)
<form action="${pageContext.request.contextPath}/login">
<table border="1px">
<tr>
<%-- 通过text获取资源包中的value --%>
<td><s:text name="login.username"></s:text></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><s:text name="login.password"></s:text></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="<s:text name='login.submit'></s:text>">
</td>
</tr>
</table>
</form>
<hr>
指定为cn.hestyle.package包范围的资源包
<form action="${pageContext.request.contextPath}/login">
<table border="1px">
<%-- 指定为cn.hestyle.package包范围的资源包 --%>
<s:i18n name="cn.hestyle.package">
<tr>
<%-- 通过text获取资源包中的value --%>
<td><s:text name="login.username"></s:text></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><s:text name="login.password"></s:text></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="<s:text name='login.submit'></s:text>">
</td>
</tr>
</s:i18n>
</table>
</form>
<hr>
指定为cn.hestyle.web.action.UserAction局部资源包
<form action="${pageContext.request.contextPath}/login">
<table border="1px">
<%-- 指定为cn.hestyle.web.action.UserAction局部资源包 --%>
<s:i18n name="cn.hestyle.web.action.UserAction">
<tr>
<%-- 通过text获取资源包中的value --%>
<td><s:text name="login.username"></s:text></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><s:text name="login.password"></s:text></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="<s:text name='login.submit'></s:text>">
</td>
</tr>
</s:i18n>
</table>
</form>
</body>
</html>
b、在Action中读取资源包内容
通过使用ActionSupport
的getText
方法,读取资源包的内容,也就是说这个Action一定要继承ActionSupport。
①、如果只配置全局资源包
访问login动作,控制台输出
②、配置全局资源包又配置包范围的资源包,全局被包范围覆盖
访问login动作,控制台输出
③、同时配置全局、包范围、局部资源包
访问login动作,控制台输出
需要注意一下,这里所谓的优先级、覆盖都是在他们都能作用于这个Action为前提下,如果一个包范围资源、局部资源对动作没有影响的情况下,是不存在覆盖的。
并且这个Action中读取资源包内容非常少用。
我这里修改了浏览器第一显示语言,所以显示的都是英文。默认是显示中文的,蛋是,由于properties文件默认编码是ISO,而IDEA中统一编码都是UTF-8,所以浏览器读取properties文件中的中文会出现乱码。在Eclipse中可以修改properties文件编码为ISO,不会出现中文乱码。
在IDEA将properties文件内容修改ISO编码请参考我的另一篇博客:
Struts2框架之项目国际化时properties文件乱码问题