【问题标题】:UTF-8 response with servlet带有 servlet 的 UTF-8 响应
【发布时间】:2013-03-29 21:33:29
【问题描述】:

我正在从 Servlet 中的 Perl 页面读取 HTTP 响应,如下所示:

public String getHTML(String urlToRead) {
        URL url;
        HttpURLConnection conn;
        BufferedReader rd;
        String line;
        String result = "";
        try {
           url = new URL(urlToRead);
           conn = (HttpURLConnection) url.openConnection();
           conn.setRequestMethod("GET");
           conn.setRequestProperty("Accept-Charset", "UTF-8");
           conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");

           rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
           while ((line = rd.readLine()) != null) {
              byte [] b = line.getBytes();
              result += new String(b, "UTF-8");
           }
           rd.close();
        } catch (Exception e) {
           e.printStackTrace();
        }
        return result;
   }

我正在用这段代码显示这个结果:

response.setContentType("text/plain; charset=UTF-8");

        PrintWriter out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8"), true);


        try {

            String query = request.getParameter("query");
            String type = request.getParameter("type");

            String res = getHTML(url);
            out.write(res);

        } finally {            
            out.close();
        }

但响应仍未编码为 UTF-8。我做错了什么?

提前致谢。

【问题讨论】:

  • 在您的 PrintWriter 中,是否有可能“UTF8”不存在但“UTF-8”存在?
  • 我试图更改它但无济于事(已编辑)
  • 你怎么知道它不是 UTF-8?
  • 您有什么证据表明urlToRead 正在以UTF-8 格式返回其内容?正如你所假设的那样。当您已经拥有String 时,为什么还要将line 转换为bytes?

标签: java servlets utf-8


【解决方案1】:

line.getBytes() 的调用看起来很可疑。如果您确定返回的内容是 UTF-8 编码的,您可能应该将其设为 line.getBytes("UTF-8")。此外,我不确定为什么它甚至是必要的。从BufferedReader 获取数据的典型方法是使用StringBuilder 继续将从readLine 检索到的每个String 附加到结果中。无需在Stringbyte[] 之间来回转换。

result 更改为StringBuilder 并执行以下操作:

while ((line = rd.readLine()) != null) {
    result.append(line);
}

【讨论】:

  • +1 表示StringBuilder。你目前的速度非常缓慢:stackoverflow.com/questions/15177987/…
  • 我最初使用的是 StringBuilder。但由于它不起作用,我尝试根据论坛上的帖子建议更改代码。
  • 好的。我将它改回 StringBuilder 并且它现在可以工作了。我不知道为什么它以前不起作用。非常感谢您的回答。 +1
【解决方案2】:

这里是你打破字符编码转换链的地方:

       while ((line = rd.readLine()) != null) {
          byte [] b = line.getBytes();  // NOT UTF-8
          result += new String(b, "UTF-8");
       }

来自 String#getBytes() javadoc:

使用平台的编码将此字符串编码为字节序列 默认字符集,将结果存储到一个新的字节数组中

而且,默认字符集可能不是 UTF-8。

但为什么首先要进行所有转换?只需从源读取原始字节并将原始字节写入消费者。它应该一直是UTF-8。

【讨论】:

    【解决方案3】:

    我在另一个场景中也遇到了同样的问题,但只要去做我相信它会奏效:

    byte[] b = line.getBytes(UTF8_CHARSET);
    

    在while循环中:

    while ((line = rd.readLine()) != null) {
              byte [] b = line.getBytes();  // NOT UTF-8
              result += new String(b, "UTF-8");
           }
    

    【讨论】:

      【解决方案4】:

      就我而言,我确实添加了另一个配置

      以前,我是这样写页面的:

      try (PrintStream printStream = new PrintStream(response.getOutputStream()) {
              printStream.print(pageInjecting);
      }
      

      我改成:

      try (PrintStream printStream = new PrintStream(response.getOutputStream(), false, "UTF-8")) {
              printStream.print(pageInjecting);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-20
        • 1970-01-01
        • 1970-01-01
        • 2011-04-13
        • 2018-01-26
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多