【问题标题】:Java Map, how to put UTF-8 string to the map correctly?Java Map,如何正确地将 UTF-8 字符串放入地图?
【发布时间】:2011-08-25 00:12:56
【问题描述】:

我有一个地图,更准确地说是 LinkedHashMap。 我想给它放一个字符串对象。 然后我读取这个值以查看实际存储的内容。 字符串本身具有非 ascii 字符(西里尔文、韩文等)。 一旦我把它放到地图上然后阅读,这些字符就会被替换为???s。 一些代码:

Map obj = new LinkedHashMap();
System.out.println("name: " + getName());  // prints "i4niac_сим_sim"
obj.put("name", getName());
System.out.println("written stuff: " + obj.get("name"));  // prints i4niac_???_sim

这里有什么诀窍? 我正在使用此映射使用 json-simple 制作 JSON 对象并将其从服务器发送到客户端。

更新:

呃,对不起所有的混乱。 首先我责怪数据存储,然后是地图,最后,不出所料,这是我在另一个地方的错。 我在应用程序引擎中发送 json 数据,将内容类型设置为“application/json”

public void doPost(HttpServletRequest req, HttpServletResponse resp) {
// ...
        resp.setContentType("application/json");
        resp.getWriter().println(jsonObj.toString());
}

无论我在后端尝试了哪些技巧,它都从未将其作为 UTF-8 发送。 改成之后

    resp.setCharacterEncoding("UTF-8");

我终于收到了非 ASCII 字符的 UTF-8 转义码。

【问题讨论】:

  • 打印结果的终端是否正确显示其他 UTF-8 字符串?可能是字体问题...
  • 嗨,你可以看到我已经完全改变了这个问题。数据是从数据存储中正确读取的,我的错误忽略了它。问题在于使用 Map,我将 UTF-8 字符串放在那里并得到“丑陋”的一个。
  • 查看编码的系统属性。我的意思是 System.getProperty("file.encoding") (JVM) 来自同一个程序。
  • 奇怪,我不明白这个问题。我得到两个输出的相同字符串 (i4niac_сим_sim)。
  • 在 Eclipse 中的 Java 6 和 Windows 7 上,我得到了正确的 UTF-8 字符串,而在控制台上,我得到了预期的丑陋字符串……我很好奇你使用的是什么 JRE/JDK?

标签: java string json utf-8 map


【解决方案1】:

你怎么知道字符被替换为??? -- 您的控制台不是设置为 ASCII 代码页或类似的吗?还是您在控制台中使用的字体不能正确处理 UTF-8 字符?您是否尝试将所有这些写入文件并在 MS Word 之类的文件中打开并验证是否是这种情况?

【讨论】:

  • 根据他的代码示例,他在将值添加到地图之前将其打印出来,并且此时显示得很好,这与控制台/字体理论相矛盾。
【解决方案2】:

Java Map,如何正确地把 UTF-8 字符串放到地图上?

字符串不可变且始终编码为 UTF-16。如果要以任何其他编码表示字符数据,则必须使用字节数组。

由于LinkedHashMap 不会改变或序列化您的字符串,因此您放入其中的对象值应该是返回的值。

我能想到的唯一解释:

  • getName() 不会每次都返回对同一个字符串的引用(很可能)
  • System.out PrintWriter 被同时修改
  • 同时修改控制台接收数据的编码

您可以发出字符串的十六进制形式以确保显示错误不是问题:

public static String toCodeUnits(String s) {
  StringBuilder sb = new StringBuilder();
  for(char codeUnit : s.toCharArray()) {
    sb.append(String.format("%04x ", (int) codeUnit));
  }
  return sb.toString();
}

对于i4niac_сим_sim,此代码将返回:

"0069 0034 006e 0069 0061 0063 005f 0441 0438 043c 005f 0073 0069 006d "

【讨论】:

    【解决方案3】:

    使用-encoding 标志重新编译您的代码

    喜欢这个

    javac -encoding UTF-8 Test3.java
    

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多