不需要转编码的I18N

先回顾一下经典的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。(如果呼声高,我也可以动手)。使用HashMap来装message可以异步访问,比Properties的同步访问效率要高。

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

时间: 2024-10-16 14:47:02

不需要转编码的I18N的相关文章

I18N 国际编码

<%@ page language="java" import="java.util.*, cn.hncu.domain.*" pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@taglib uri="http://java.sun.com/j

查看系统当前的编码——local -a ; echo $LANG

查看系统所有的编码:locale  (-a) 查看系统当前的编码:echo $LANG 修改系统的编码:然后修改/etc/sysconfig/i18n,如改成中文编码: LANG=en_US.UTF-8

字符集编码

http://blog.chinaunix.net/uid-20761674-id-3486843.html http://www.searchtb.com/2012/04/chinese_encode.html 编码问题的例子 在windows自带的notepad(记事本)程序中输入“联通”两个字,保存后再次打开,会发现“联通”不见了,代之以“???”的乱码.这是windows平台上典型的中文编码问题.即文件保存的时候是按照ANSI编码(其实就是GB2312,后面会详细介绍)保存,打开的时候程

javaweb学习总结(三十一)——国际化(i18n)

一.国际化开发概述 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化(internationalization)又称为 i18n(读法为i 18 n,据说是因为internationalization(国际化)这个单词从i到n之间有18个英文字母,i18n的名字由此而来) 二.合格的国际化软件 软件实现国际化,需具备以下两个特征: 1.对于程序中固定使用的文本元素,例如菜单栏.导航条等中使用的文本

jQuery之前端国际化jQuery.i18n.properties

jQuery之前端国际化jQuery.i18n.properties jQuery.i18n.properties是一款轻量级的jQuery国际化插件,能实现Web前端的国际化. 国际化英文单词为:Internationalization,又称i18n,“i”为单词的第一个字母,“18”为“i”和“n”之间单词的个数,而“n”代表这个单词的最后一个字母.jQuery.i18n.properties采用.properties文件对JavaScript进行国际化.jQuery.i18n.proper

linux系统字符编码详解

众所周知,地球上的语言多种多样,在计算机世界,自然也是要适应各种语言.我们安装各种系统的时候也是明示了要选择语言环境和支持的语言环境. 而linux系统的字符编码设置尤为复杂,这可能也是没有考虑到非技术人员去研究这些东西吧. 我遇到的事情是这样的,我们使用了docker,但是docker容器里的语言环境经常莫名错乱,搞得很头痛,所以偶尔就要切换,或者生成其他字符集.所以现在假设我们需要切换一个中文语言环境,而切换了之后是乱码的,也就是没用的. 基本上,乱码的原因就是没加载到合适的字符编码环境,即

Struts2(三)更改字符编码

一.导入包和struts配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <stru

Struts2 开发 编码问题汇总

Struts2:中文乱码问题 1.中文乱码问题到处都有,因为编码格式一人一套,页面有页面编码格式,action有action编码格式,servlet有servlet编码格式,数据库有数据库编码格式,而且不同数据库还有不同的格式,五花八门,应有尽有. 如果网页要支持国际化,那字符编码格式只能是选择UTF-8,别的都不好使.而我们平时选择的中文编码格式一般是gb2312和gbk,因为这两个对中文支持性最好,尤其是gbk. 在开发一个WEB项目时,最好统一一种编码格式,比如统一为gb2312,那就不要

springMVC项目国际化(i18n)实现方法

SpringMVC项目国际化(i18n)实现方法 按照作息规律,每周五晚必须是分享知识的时间\(^o^)/~,这周讲点儿啥呢,项目需要逼格,咱们国际化吧(* ̄rǒ ̄)~,项目中碰到这类需求的童鞋可能并不多,但偶尔用到也会比较费时间滴;-),不如驻足本帖片刻吧︿( ̄︶ ̄)︿ 额,嗯~,记得一开始从事软件开发时在一个很轻量级的项目中碰到了一个貌似叼炸天的需求,什么?国际化?没听说过,不知道怎么玩儿...,谷歌翻帖快一周,大神们的神贴也看了许久,可就是解决不了我的项目需求,怎么办,加大神Q骚扰之~~(