【问题标题】:Java "jsonify" simple string ("äh" -> "\u00e4h")Java "jsonify" 简单字符串 ("äh" -> "\u00e4h")
【发布时间】:2017-05-26 08:43:32
【问题描述】:

在 Python 中我可以执行以下操作

# -*- coding: utf-8 -*-
import json
print json.dumps("äh")

在 PHP 中我可以执行

json_encode('äh')

这两个结果都是"\u00e4h"

如何在 Java 中做同样的事情?我尝试使用JSONObject,但它只接受已经包含键值的 JSON 字符串。

【问题讨论】:

  • 考虑使用 Gson 来自 google 的库

标签: java android json string


【解决方案1】:

在 Java 中使用 JSON 实用程序打印 UTF-8 代码点有点过头了。

在 Java8 中使用 IntStream String.codePoints():

String text = "äh";
text.codePoints().forEach(c -> System.out.print("\\u" + String.format("%04Xh ", c)));

在早期的 Java 版本中(包括 Android SDK):

String text = "äh";
for(int i = 0; i < text.length(); i++) {
    System.out.print("\\u" + String.format("%04Xh ", text.codePointAt(i)));
}

两者都导致:

\u00E4h \u0068h 

【讨论】:

  • 对不起,忘了说这是在 Android 上,所以没有 Java 8
  • 这个\u0068h来自哪里?
  • \u00E4h 末尾的hh,它是äh 中的第二个字符,它不需要被编码为兼容JSON。
  • 正在转换的字符串中有两个字母 - 每个都返回其代码点
  • 我拒绝更改标题,因为 JSON 部分很重要。
【解决方案2】:

对于 JSON,您需要将某些字符转义为 Unicode 转义序列 (\u1234)。在大多数 Java JSON 库中,都是这样完成的(取自 here):

/**
 * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
 * @param s
 * @return
 */
public static String escape(String s){
    if(s==null)
        return null;
    StringBuffer sb = new StringBuffer();
    escape(s, sb);
    return sb.toString();
}

/**
 * @param s - Must not be null.
 * @param sb
 */
static void escape(String s, StringBuffer sb) {
    for(int i=0;i<s.length();i++){
        char ch=s.charAt(i);
        switch(ch){
        case '"':
            sb.append("\\\"");
            break;
        case '\\':
            sb.append("\\\\");
            break;
        case '\b':
            sb.append("\\b");
            break;
        case '\f':
            sb.append("\\f");
            break;
        case '\n':
            sb.append("\\n");
            break;
        case '\r':
            sb.append("\\r");
            break;
        case '\t':
            sb.append("\\t");
            break;
        case '/':
            sb.append("\\/");
            break;
        default:
            //Reference: http://www.unicode.org/versions/Unicode5.1.0/
            if((ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')){
                String ss=Integer.toHexString(ch);
                sb.append("\\u");
                for(int k=0;k<4-ss.length();k++){
                    sb.append('0');
                }
                sb.append(ss.toUpperCase());
            }
            else{
                sb.append(ch);
            }
        }
    }//for
}

据我所知,上述方法不会转义您的 ä 字符,因为它不需要转义,只要您使用 UTF-8 作为生成的 JSON 文本的编码,我猜你想发送到某个地方。

因此,要么使用 UTF-8 作为内容编码并且不要转义 ä(不需要),或者修改上面的方法以使用 ch &gt; 127 转义所有内容。即:

[...]
        default:
            //Reference: http://www.unicode.org/versions/Unicode5.1.0/
            if((ch > 127) || (ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')){
                String ss=Integer.toHexString(ch);
                sb.append("\\u");
                for(int k=0;k<4-ss.length();k++){
                    sb.append('0');
                }
                sb.append(ss.toUpperCase());
            }
            else{
                sb.append(ch);
            }
[...]

然后它应该可以工作......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 2021-02-25
    相关资源
    最近更新 更多