如何将UTF8转换为Unicode

7

我尝试将一个UTF8字符串转换为Java Unicode字符串。

String question = request.getParameter("searchWord");
byte[] bytes = question.getBytes();
question = new String(bytes, "UTF-8");

输入的是中文字符,当我比较每个字符的十六进制代码时,它们都是相同的中文字符。因此,我非常确定字符集是UTF8。

我错在哪里了?

5个回答

11
在Java中,不存在所谓的“UTF-8字符串”,一切都是Unicode。
如果您调用String.getBytes()而没有指定编码,则会使用平台默认编码,这几乎总是一个糟糕的想法。
您不应该做任何事情来获取正确的字符 - 请求应该为您处理所有内容。如果它没有这样做,那么很可能已经丢失了数据。
能否举个实际出错的例子?通过指定接收到的字符串中字符的Unicode值(例如,通过使用toCharArray()然后将每个char转换为int),并说明您期望接收到的内容。
编辑:要诊断此问题,请使用以下代码:
public static void dumpString(String text) {
    for (int i = 0; i < text.length(); i++) {
        System.out.println(i + ": " + (int) text.charAt(i));
    }
}
请注意这将提供每个Unicode字符的十进制值。如果您有一个方便的十六进制库方法,可以使用它来提供十六进制值。主要问题是它将转储字符串中的Unicode字符。

我需要将这个字符转换为Unicode。例如,我得到了229 145 138的十进制表示,根据http://www.ansell-uebersetzungen.com/gbuni.html是正确的,因为它的十六进制表示是E5 91 8A。 - Rob Hufschmitt
在我看来,该请求发送了正确的字符,但是我无法在Java中读取这些字符,需要将其转换为Unicode。 - Rob Hufschmitt
@Rob:不,应该在字符串中显示为U+544A。你引用的十六进制表示是UTF-8表示法——这永远不会是字符串本身的内容。你说你“得到”了229 145 138——你是怎么做的?我会在我的答案中加入一些诊断代码。 - Jon Skeet

2

首先确保数据实际上已经以UTF-8编码。

不同的浏览器在发送HTML表单数据时使用的编码存在一些不一致性。从Web表单发送UTF-8编码的数据的最安全方法是将该表单放在一个带有Content-Type: text/html; charset=utf-8头或包含<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />元标记的页面上。


现在,在第一次调用request.getParameter()之前,在您的servlet中调用request.setCharacterEncoding("UTF-8"),以便正确解码数据。

servlet容器会为您处理编码。如果您正确使用setCharacterEncoding(),可以期望getParameter()返回普通的Java字符串。


现在当我转换时,每个字符都得到了Unicode 63的表示,所以我猜我的转换仍然有问题。 - Rob Hufschmitt
@Rob,您不需要进行任何手动转换。您应该调用 setCharacterEncoding("UTF-8") 并使用 request.getParameter() 来获取普通的 Java Unicode 字符串。我猜您的代码也可以处理普通的 ASCII 字符? - Alex Jasmin
请使用@Jon Skeet的代码片段获取每个字符的Unicode代码点,而不是String.getBytes() - Alex Jasmin

0
String question = request.getParameter("searchWord");

在您的servlet代码中,您所要做的就是这样。此时,您无需处理编码、字符集等问题。所有这些都由servlet基础设施处理。当您注意到显示“�”、“?”、“ü”之类的问题时,可能是客户端发送的请求有问题。但是,如果不了解基础设施或已记录的HTTP流量,很难确定出错的原因。


0

另外,您可能需要一个特殊的过滤器来处理请求的编码。例如,在Spring框架中存在这样的过滤器org.springframework.web.filter.CharacterEncodingFilter


-1

可能。

 question = new String(bytes, "UNICODE"); 

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