【问题标题】:Response has 2 bytes per character in Netty响应在 Netty 中每个字符有 2 个字节
【发布时间】:2019-02-06 11:03:32
【问题描述】:

在 Netty 中,我通过在 body 中输入字符串来创建响应:

        DefaultFullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, httpResponse.getHttpResponseStatus());
        if (body != null) {
            ByteBuf buf = Unpooled.copiedBuffer(body, CharsetUtil.UTF_8);
            res.content().writeBytes(buf);
            buf.release();
            res.headers().set(HttpHeaderNames.CONTENT_LENGTH, res.content().readableBytes());
        }

当我查看响应时,我看到content-length 是字符串中字符长度的两倍。我知道 Java 字符串每个字符包含 2 个字节,但我不知道在返回请求时如何在 Netty 中防止这种情况发生。

当我查看 Cloudflare 响应时,这些响应包含每个字符一个字节。所以必须有办法改变这一点。想法?

【问题讨论】:

  • res.content().clear(); res.content().writeBytes(buf); 也许内容包含两倍的数据。

标签: java http encoding character-encoding netty


【解决方案1】:

正如@Chris O'Toole 在How to convert a netty ByteBuf to a String and vice versa 中展示的那样,我们必须

  • 首先使用所需的字符集将字符串转换为字节数组(UTF-8 可以正常工作)String.getBytes(Charset)
  • 然后Unpooled.wrappedBuffer(byte[]) 使用字节数组代替 字符串。

如@rossum 所述,大多数字符每个字符一个字节。

【讨论】:

    【解决方案2】:

    使用 US_ASCII 字符集而不是 UTF-8。没测试过,试试吧。

    【讨论】:

    • 对于最常见的字符,UTF-8 只需要一个字节。每个字符两个字节要么是非拉丁字母,要么是原始的 UTF-16,每个字符总是两个字节,Java 默认 IIRC。
    • @rossum copiedBuffer 说:“创建一个新的大端缓冲区,其内容是在指定的 {@code charset} 中编码的指定 {@code string}。新缓冲区的 {@code readerIndex} 和 {@code writerIndex} 分别是 {@code 0} 和编码字符串的长度。"如果您所说的和规范是正确的,UTF-8 应该可以正常工作,即使原始 Java 字符串是 UTF-16。你所说的是我认为 UTF-8 应该如何工作。可能是 Netty 4.1.15 中的错误?
    • @Oliver 你在{@code charset} 中指定了什么字符集?
    • @rossum UTF-8,我希望缓冲区从 String 复制到 UTF-8。我发现了两件事:netty.io/4.1/api/io/netty/util/AsciiString.htmlstackoverflow.com/questions/40289204/… - 明天将尝试这些并发布结果。
    • 正如@Chris O'Toole 在stackoverflow.com/questions/40289204/… 中显示的那样,我们必须首先使用所需的字符集将字符串转换为字节数组(UTF-8 工作正常)String.getBytes(Charset),然后Unpooled.wrappedBuffer(byte[]) 使用字节数组而不是字符串。正如@rossum 所说,大多数字符每个字符一个字节。
    猜你喜欢
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 2011-03-16
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2017-08-24
    相关资源
    最近更新 更多