【问题标题】:Why do I have to encode a utf-8 parameter String to iso-Latin and then decode as utf-8 to get Java utf-8 String?为什么我必须将 utf-8 参数字符串编码为 iso-Latin,然后解码为 utf-8 才能获得 Java utf-8 字符串?
【发布时间】:2016-03-22 16:06:19
【问题描述】:

我有一个 Java servlet,它接受一个参数字符串 (inputString),它可能包含来自标记为 utf-8 的网页的希腊字母。在将其发送到数据库之前,我必须将其转换为新字符串(utf8String),如下所示:

String utf8String = new String(inputString.getBytes("8859_1"), "UTF-8");

这行得通,但是,我希望得到赞赏,我讨厌做我不理解的事情,即使它行得通。

从 Java 文档中的方法描述中,getBytes() 方法“使用命名字符集将此字符串编码为字节序列,将结果存储到新的字节数组中”,即我将其编码为 8859_1 — isoLatin。并且来自构造函数描述“通过使用指定的字符集解码指定的字节数组来构造一个新的字符串”,即将字节数组解码为 utf-8。

有人可以向我解释为什么这是必要的吗?

【问题讨论】:

  • 如果您手动编码 Ajax 调用,您在调用中使用什么字符编码,即在您发送到服务器的 POST 方法上?你能捕获 HTTP 请求并显示它吗?
  • 我正在使用 GET 请求并查看我的 js 我没有看到指定请求的字符编码。我正在使用 javascript encodeURIComponent() 方法对字符串进行编码。我找不到请求 - 我正在使用 Mac Safari,而且一定是在开发人员控制台中查找错误的位置。我只是想知道我是否已经过火了。我正在尝试写出我多年来在十几个 Java 应用程序中使用的所有 utf-8 编码内容。我应该在发布之前检查这个操作是否真的有必要,所以我可以确定如何破解它。请给我一点时间。
  • 好的,我有另一个更简单的 servlet,它有 javascript 创建一个假表单来将字符串从 Web 输入发送到 Servlet。 HTTP 请求包含希腊字符,因为它是我可以在我的 URL 字段中看到的获取请求:localhost:8080/MidgutAtlas/…。但我认为您不能在 HTTP 请求中指定字符集,只能在响应中指定字符集。而且,是的,这行代码是必要的。
  • αgreek small letter alpha,但如果您在值α-Est4 上调用了encodeURIComponent(),则α 应该被转义为%CE%B1(UTF-8 十六进制) .
  • 我同意。 Safari 可能很聪明,并为用户呈现了这个。假设您无法指定请求的字符集,因为最初它只是一个 URL,并且假定为 ISO-Latin-1,不管 Web 应用程序的参数如何,我将 8859_1 更改为 UTF-8,假设所有Iso-Latin-1 字符在 UTF-8 中是相同的,任何多字节字符都是显而易见的。然而,这给了我一个回应没有找到“α-Est4”的结果。这些是 %CE 和 %B1 的单独值。也许问题是 URL 转义不是 unicode,因此您必须先获取字节。

标签: java utf-8 character-encoding


【解决方案1】:

我的问题是基于对用于 HTTP 请求的字符集的误解。我假设因为我将发送请求的网页标记为 UTF-8,所以请求将作为 UTF-8 发送,因此发送到 servlet 的参数中的希腊字符将被读取为 UTF- HttpRequest.getParameter() 方法的 8 个字符串(我的代码行中的“inputString”)。不是这种情况。

HTTP 请求以 ISO-8859-1 (POST) 或 ASCII (GET) 格式发送,它们通常是相同的。这是 URI 语法规范的一部分——感谢 Andreas 将我指向http://wiki.apache.org/tomcat/FAQ/CharacterEncoding 进行解释。

我还忘记了请求的希腊字母(例如 α)的编码是 URL-encoding,它产生 %CE%B1。 getParameter() 通过将其解码为两个 ISO-8859-1 字符 %CE 和 %B1 — Î 和 ±(我检查了这个)来处理这个问题。

我现在明白为什么需要将其转换为字节数组并将字节解释为 UTF-8。 0xCE 不代表 UTF-8 中的单字节字符,因此它使用下一个字节 0xB1 寻址,被解释为 α。 (在 UTF-8 中,Î 是 0xC3 0x8E,± 是 0xC2 0xB1。)

【讨论】:

    【解决方案2】:

    解码时,你能不能用一个解码器方法创建一个类,它把字节[]作为参数和 将其作为字符串返回?这是我以前用过的一个例子。

    public class Decoder
    {           
       public String decode(byte[] bytes) 
       { 
        //Turns the bytes array into a string
        String decodedString = new String(bytes);
        return decodedString;
       }
    }
    

    尝试使用它而不是 .getBytes()。希望这行得通。

    【讨论】:

      猜你喜欢
      • 2011-08-09
      • 2014-01-18
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多