木心

毕竟几人真得鹿,不知终日梦为鱼

导航

java国际化

 Java程序国际化的关键类是ResourceBundle和Locale,ResourceBundle根据不同的Locale加载语言资源文件,在根据指定的key取得语言资源文件中的字符串。

从资源文件中取出的字符串可能包含占位符,可以使用MessageFormat来处理包含占位符的字符串。综上可知,Java程序的国际化主要通过三个类完成:

  1)java.util.ResourceBundle: 用来加载国家、语言资源包;

  2)java.util.Locale: 用于封装特定的国家/区域、语言环境;

  3)java.util.MessageFormat: 用于格式化带占位符的字符串。

 

下面简单演示如何在Java web程序中集成国际化功能,最后简单总结了ResourceBundle、Locale、MessageFormat这三个类的使用。

 

1、将resourceBundle放进request域中

public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        
        request.setAttribute("resourceBundle", Utils.getResourceBundle(request));
  }
}

  Utils类:

package com.oy;
import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.springframework.web.method.HandlerMethod; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.mysql.jdbc.StringUtils; import amberai.jweb.utils.Config; import amberai.jweb.utils.RedisAccess; import amberai.jweb.utils.UtilFunctions; import redis.clients.jedis.Jedis; public class Utils {   public static String getLanguage(HttpServletRequest request) { String language = ""; if (request == null) return language; // priority: url?l=en-us > Cookie:language=zh-cn language = request.getParameter("l"); if (language == null || Config.LANGUAGECONFIG.get(language.toLowerCase()) == null) { language = Utils.getLanguageByCookie(request); } if (language == null || Config.LANGUAGECONFIG.get(language.toLowerCase()) == null) { language = "en-us"; // default "en-us" } return language; } public static String getLanguageByCookie(HttpServletRequest request) { String language = ""; if (request == null) return language; Cookie[] cookies = request.getCookies(); if (cookies == null || cookies.length == 0) { return language; } for (Cookie cookie : cookies) { if ("language".equalsIgnoreCase(cookie.getName())) { language = cookie.getValue(); } } return language; } public static ResourceBundle getResourceBundle(HttpServletRequest request) { String language = Utils.getLanguage(request); String[] languages = language.split("-"); Locale locale = null; if (languages.length >= 2) { locale = new Locale(language.split("-")[0], language.split("-")[1]); } else if (languages.length == 1) { locale = new Locale(language.split("-")[0], "ES"); } return ResourceBundle.getBundle("i18n/MessgesBundle", locale); } }

 

  Config类

public static final Map<String, String> LANGUAGECONFIG = new HashMap<String, String>() {
    private static final long serialVersionUID = 1L;
    {
        put("en-us", "en-US");
        put("zh-cn", "zh-CN");
        put("es", "es-ES");
        put("pt-br", "pt-BR");
    }
};

 

2、使用resourceBundle

@IsLogin
@RequestMapping(value = "/userlevel", method = RequestMethod.GET)
@ResponseBody
public JSONObject getUserLevelByUserid(HttpServletRequest request) {
    Integer uid = (Integer) request.getAttribute("uid");
    ResourceBundle resourceBundle = (ResourceBundle) request.getAttribute("resourceBundle");
    
    UserLevel userLevel = userLevelService.getUserLevelByUserid(uid);
    if (userLevel == null) {
        String message = UtilFunctions.getMessage(resourceBundle, "USER_LEVEL_NULL");
        return new Response(ErrCode.PARAM_INVALID, message).toJson();
    }

    JSONObject response = new JSONObject();
    response.put("code", 0);
    response.put("data", userLevel);
    return response;
}

  

  UtilFunctions.getMessage():资源文件为UTF-8的编码处理

public static String getMessage(ResourceBundle resourceBundle, String key, Object... args) {
    String msg = "";
    
    if (resourceBundle == null || key == null || key.isEmpty()) return msg;
    
    if (args == null || args.length == 0) {
        msg = resourceBundle.getString(key);
        try {
            msg = new String(msg.getBytes("ISO-8859-1"), "UTF-8");
            return msg;
        } catch (UnsupportedEncodingException e) {
            UtilFunctions.log.error("UtilFunctions getMessage error, msg:{}, exception:{}", e.toString(), e);
            UtilFunctions.reportError("UtilFunctions getMessage: " + e.toString(), e);
            return msg;
        }
    }
    
    msg = MessageFormat.format(resourceBundle.getString(key), args);
    try {
        msg = new String(msg.getBytes("ISO-8859-1"), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        UtilFunctions.log.error("UtilFunctions getMessage error, msg:{}, exception:{}", e.toString(), e);
        UtilFunctions.reportError("UtilFunctions getMessage: " + e.toString(), e);
        return msg;
    }
    
    return msg;
}

 

3、资源文件

  

   MessagesBundle_en_US.properties

#Common
PARAM_MISS=param: {0} is empty
PARAM_INVALID=param: {0} is invalid
PARAM_INCORRECT=param: {0} is incorrect
PARAM_FORMAT_INCORRECT=param: {0} format is incorrect
NO_RECORDS_FOUND=No {0} found
SYSTEM_BUSY=The system is busy. Please try again later!
PASS_ERROR=Password error
PAY_PASS_ERROR=Transaction password error

#UserController
REPAY_PASS_ERROR=Confirm password error
PASS_FORMAT_ERROR=Password format error
#OLD_PASS_FORMAT_ERROR=Old password format error
NEW_PASS_FORMAT_ERROR=New password format error
OLD_PASS_ERROR=Old password error
NEW_OLD_PASS_SAME=New password can not be the same as the old one
PAY_LOGIN_PASS_SAME=Transaction password can not be the same as login password
LOGIN_PAY_PASS_SAME=Login password can not be the same as transaction password
NO_SUCH_USER=No such user: {0}
ACCOUNT_FROZEN=The account has been frozen: {0}
INVITATION_CODE_ERROR=Invitation code is invalid
USER_LEVEL_NULL=User level is empty

#TradeController
PLACE_ORDER_PRICE_ERROR=Price cannot be less than {0} times the current price and more than {1} times the current price
PLACE_ORDER_TRIGGER_PRICE_ERROR=Stop price cannot be less than {0} times the price and more than {1} times the price
PLACE_ORDER_NUM_ERROR=Trade number can not be less than {0}
PLACE_ORDER_NO_ENOUGH_COIN=No enough {0}
QUERY_ORDER_NULL=Query order failed, hashId is invalid
QUERY_USER_VALIDATION_ERROR=Can not query orders that are not your own
CANCEL_ORDER_NULL=Cancel order failed, hashId is invalid
CANCEL_USER_VALIDATION_ERROR=Cancel order failed. Can not cancel orders that are not your own
CANCEL_TYPE_ERROR=Market order can not be cancelled
CANCEL_STATUS_ERROR=Order with status {0} can not be cancelled

 

4、国际化相关API

  Locale

Locale defaultLocale = Locale.getDefault();
System.out.print("country=" + defaultLocale.getCountry());// country=CN
System.out.println(", language=" + defaultLocale.getLanguage());// language=zh

Locale locale1 = Locale.CHINA;
System.out.print("country=" + locale1.getCountry());// country=CN
System.out.println(", language=" + locale1.getLanguage());// language=zh

Locale locale2 = Locale.CHINESE;
System.out.print("country=" + locale2.getCountry());// country=
System.out.println(", language=" + locale2.getLanguage());// language=zh

Locale locale3 = Locale.TRADITIONAL_CHINESE;
System.out.print("country=" + locale3.getCountry());// country=TW
System.out.println(", language=" + locale3.getLanguage());// language=zh

Locale locale4 = Locale.SIMPLIFIED_CHINESE;
System.out.print("country=" + locale4.getCountry());// country=CN
System.out.println(", language=" + locale4.getLanguage());// language=zh

   

  ResourceBundle

// 创建ResourceBundle:根据指定的国家a、语言A 加载资源文件 baseName_a_A.properties
ResourceBundle resourceBundle = ResourceBundle.getBundle("i18n/baseName", new Locale("a", "A"));
// 打印从资源文件获取的值
System.out.println(resourceBundle.getString("HELLO"));

resourceBundle = ResourceBundle.getBundle("i18n/baseName", new Locale("b", "B"));
System.out.println(resourceBundle.getString("HELLO")); // 资源文件是UTF-8编码。这里打印结果乱码

// 处理乱码
String msg = resourceBundle.getString("HELLO");
try {
    msg = new String(msg.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

System.out.println(msg);

  测试上面的代码之前,在src下新建文件夹i18n,然后再i8n文件夹内新建baseName_a_A.properties和baseName_b_B.properties资源文件。资源文件的编码为UTF-8。

  baseName_a_A.properties添加:HELLO=hello

  baseName_b_B.properties添加:HELLO=您好

 

  MessageFormat

String pattern = "hello {0}";
String message = MessageFormat.format(pattern, "世界");
System.out.println(message); // hello 世界

 

 

参考资料

  (1)https://www.cnblogs.com/jyh317/p/3608048.html

  (2)https://cloud.tencent.com/developer/news/242356

  (3)https://blog.csdn.net/deniro_li/article/details/80451866

posted on 2019-05-20 11:36  wenbin_ouyang  阅读(2567)  评论(0编辑  收藏  举报