从Java属性文件中读取Unicode字符

4
请帮我在Java的属性文件中按原样读取UNICODE字符。例如:如果我传递键“Account.label.register”,它应该返回“\u5BC4\u5B58\u5668”,而不是其字符表示,如“寄存器”。以下是我的样例属性文件:

file_ch.properties

Account.label.register = \u5BC4\u5B58\u5668 
Account.label.login = \u767B\u5F55 
Account.label.username = \u7528\u6237\u540D 
Account.label.password = \u5BC6\u7801 

谢谢。

你好,我正在使用以下Java代码读取属性文件:

@Override
public ResourceBundle getTexts(String bundleName) {
    ResourceBundle myResources = null;
    try {
        myResources = ResourceBundle.getBundle(bundleName, getLocale());
    } catch (Exception e) {
        myResources = ResourceBundle.getBundle(getDefaultBundleKey(), getLocale());
    }
    return myResources;
}

使用上述方法是可以的,我能得到中文字符。但是对于我应用程序中的一些ajax请求,我需要在X-JSON标题中传递中文文本。下面给出示例代码:

    HashMap<String, List<String>> map = new HashMap<String, List<String>>();
    List<String> errors = new ArrayList<String>();
    errors.add(str);   /*ex: str = "无效的代码" , value taken from properties file through resource bundle*/
    map.put("ERROR", errors);
    JSONObject json = JSONObject.fromObject(map);
    response.setCharacterEncoding("UTF-8");
    response.setHeader("X-JSON", json.toString());
    response.setStatus(500);

我正在传递英语例子str="Invalid Code",X-JSON标头携带信息如原样。但是,如果str="无效的代码"(中文或其他任何文本),X-JSON标头会像下面的响应一样携带空文本:

 response :

 connection:close
 Content-Encoding:gzip
 Content-Type:text/html;charset=UTF-8
 Date:Wed, 08 Jun 2016 10:17:43 GMT
 Server:Apache-Coyote/1.1
 Transfer-Encoding:chunked
 Vary:Accept-Encoding
 X-JSON:{"ERROR":["Invalid Code"]}

然而,如果“错误”包含中文文本,例如:“无效的代码”
响应:
 connection:close
 Content-Encoding:gzip
 Content-Type:text/html;charset=UTF-8
 Date:Wed, 08 Jun 2016 10:17:43 GMT
 Server:Apache-Coyote/1.1
 Transfer-Encoding:chunked
 Vary:Accept-Encoding
 **X-JSON:{"ERROR":["  "]}**   /*expecting the response X-JSON:{"ERROR":["无效的代码"]}*/

由于中文文本为空,我考虑通过X-JSON标头发送Unicode,如下所示。
{"ERROR":["\u65E0\u6548\u7684\u4EE3\u7801"]}  

在评估X-JSON标头后,希望使用JavaScript代码解析Unicode字符,如下所示:

var json;
  try {
    json = xhr.getResponseHeader('X-Json');
  } catch (e) {
    alert(e);
 }

  if (json) {
    var data = eval('(' + json + ')'); 
    decodeMsg(data);
  }


  function decodeMsg(message) {
    var mssg =  message;
    var r = /\\u([\d\w]{4})/gi;
    mssg = mssg.replace(r, function (match, grp) {
        return String.fromCharCode(parseInt(grp, 16)); } );
    mssg = unescape(mssg);

    return mssg;
 }

请提出建议。谢谢。


2
请展示一下你目前尝试过的内容。 - AlexR
2
你为什么想要使用Unicode转义? - Kayaman
感谢您的及时回复。请查看我编辑过的帖子,其中包含有关从属性文件中读取Unicode字符的需求的详细说明。 - rajani chowdhary
2个回答

3

回答更新:

.properties文件的原始编码是拉丁字母表一号(Latin-1, ISO-8859-1)(éö)。

这需要对全Unicode字符范围进行u转义。

然而,新版本的java首选utf-8。因此,您可以将.properties文件保留在utf-8中!这是一个巨大的改进。


原始回答: java 1中使用ISO-8859-1的.properties。

错误在于HTTP标题行采用ISO-8859-1,基本的拉丁字母表一号。

解决方法是使用UTF-8字节的%XX转换(在这种情况下)。但是,在JSON的情况下,您最好只做您想要的操作。

因此,您希望发送u转义的Unicode,使用\uXXXX。由于不仅Java,而且JavaScript/JSON也知道此约定,因此您只需要在服务器上使用此u转义。

static String uescape(String s) {
    StringBuilder sb = new StringBuilder(s.length() * 6);
    for (int i = 0; i < chars.length; ++i) {
        char ch = s.charAt(i);
        if (ch < 128) {
            sb.append(ch);
        } else {
            sb.append(String.format("\\u%04X", (int) ch));
        }
    }
    return sb.toString();
}

errors.add(uescape(str));

这个函数会将所有非ASCII字符(>=128)转换成4位十六进制数,并且严格遵循该格式。

或者使用apache-commons库中的 StringEscapeUtils.escapeJava 函数,它还会处理引号、\n等内容,更加安全。


非常感谢您,Joop Eggen先生。这对我有用。我为此苦苦挣扎了很多天。它在完成我的任务方面为我节省了很多。我非常感激您,先生。我还从您那里得到了清晰的解释。 - rajani chowdhary

1

通过加倍反斜杠来转义属性文件中的反斜杠:

Account.label.register = \\u5BC4\\u5B58\\u5668 
Account.label.login = \\u767B\\u5F55 
Account.label.username = \\u7528\\u6237\\u540D 
Account.label.password = \\u5BC6\\u7801 

嗨,我会接受你的答案,但是双重转义它们将不会在像 <s:text name="Account.label.register"/> 这样的 jsp 文件中翻译文本。只有在少数情况下我需要读取 Unicode 字符。请查看我编辑过的帖子,了解关于需要 Unicode 字符的情况。如果可能,请提供建议。谢谢。 - rajani chowdhary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接