先回顾一下经典的I18N,
message_zh.properties
our.company=\u9999\u6E2F\u5BBD\u9891
our.target=\u6210\u5C31\u9999\u6E2F\u66F4\u7F8E\u597D\u5BB6\u56ED
用spring MVC的话,JSP上这样写 (烦人spring 的config 省略)
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
…
<label><spring:message code='our.company'/></label>
<label><spring:message code='our.target'/></label>
…
过了两天老板叫你把上面“美好”改成“幸福”,要查找和修改\uXXXX的内容,OMG,头大了有木有。即使有I18N的工具,导来导去的也不方便。究其原因是因为Java的I18N,用到了类Properties,Properties以iso8859-1编码读文件,各种语言都要转成\uXXXX这种不方便人直接阅读编码。
这都是十几年前的方案了,早就该改进了。幸好我们有伟大的UTF-8,使用UTF-8的文件,我们和Java都能读懂。让我们开始新的旅程:
1. 写资源文件
msg_zh.prop (使用.prop文件是为了不让eclipse把文件内容转成\uXXXX的格式)
our_company=香港宽频
our_target=成就香港更美好家园
将文件以utf-8编码存盘,明文保存就可以了,方便查看修改,放在classpath里面便于加载。注意,key里面不能用’.’,要使用java变量名的命名规则,即字母和下划线。
2. 加载资源
既然不能使用Properties来加载,我们就自己写一个资源加载类
public class MsgUtil {
private static Logger log = Logger.getLogger(MsgUtil.class);
private static Map<String, String> msgZh = new HashMap<String, String>();
private static Map<String, String> msgEn = new HashMap<String, String>();
static {
try {
loadProp(msgZh, "/resource/i18n/msg_zh.prop");
loadProp(msgEn, "/resource/i18n/msg_en.prop");
} catch (Exception e) {
log.error("MsgUtil init error.", e);
}
}
private static void loadProp(Map<String, String> p, String cpFile) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(
MsgUtil.class.getResourceAsStream(cpFile), "utf-8"));
String line, key, value;
int pos;
while ((line=br.readLine()) != null) {
if (line.startsWith("#")) continue;
pos = line.indexOf('=');
if (pos > 0) {
key = line.substring(0, pos);
value = line.substring(pos + 1);
p.put(key.trim(), value.trim());
}
}
} finally {
if (br != null) br.close();
}
}
public static String getString(String key){
return getString(key, getLocale());
}
public static String getString(String key, String locale) {
if (key != null && locale != null) {
return getProp(locale).get(key);
} else {
LogUtil.error("Key="+key+", lang="+locale);
}
return "!"+key+"!";
}
public static Map<String, String> getProp(String locale) {
return K.en.equals(locale) ? msgEn : msgZh;
}
}
使用utf-8读入资源文件。由于我平常遇到的情况比较简单,只有中、英文,写这样一个Util类就够用了。如果大家有兴趣可以写个I18nBundle来代替Java自带的ResourceBundle。(如果呼声高,我也可以动手)。
3. 获取locale
经典的方法是从Request header中获取locale,但我们的情况不需要这么上纲上线。先给一个缺省的中文locale(zh),然后把它记在session和cookie中,如果用户不爱看,就把它改成英文locale(en),当然要更新session和cookie
4. 将资源应用到jsp中
前方高能!请注意!!
先加一个拦截器,以spring MVC为例 (写一般的filter也可以)
public class GlobalInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse res,
Object arg2) throws Exception {
request.setAttribute("i18n", MsgUtil.getProp(getLocale()));
…
return true;
}
…
}
看好了,每个request都加了一个“i18n”的bean,这样在jsp里面用就爽了。
…
<label>${i18n.our_company}</label>
<label>${i18n.our_target}</label>
…
在Java code里面用也很简单,
MsgUtil.getString(“our_company”);
MsgUtil.getString(“our_target”, getLocale());
…
如果要带参数,可以研究一下java.text.MessageFormat
转载于:https://blog.51cto.com/wikiou/1836304