【问题标题】:How to correctly read url content with utf8 chars?如何使用 utf8 字符正确读取 url 内容?
【发布时间】:2011-06-01 02:32:41
【问题描述】:
    public class URLReader {
         public static byte[] read(String from, String to, String string){
          try {
           String text = "http://translate.google.com/translate_a/t?"+
                        "client=o&text="+URLEncoder.encode(string, "UTF-8")+
                        "&hl=en&sl="+from+"&tl="+to+"";

           URL url = new URL(text);
           BufferedReader in = new BufferedReader(
                        new InputStreamReader(url.openStream(), "UTF-8"));
           String json = in.readLine();
           byte[] bytes = json.getBytes("UTF-8");
           in.close();
           return bytes;
                    //return text.getBytes();
          }
          catch (Exception e) {
           return null;
          }
         }
        }

和:

public class AbcServlet extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  resp.setContentType("text/plain;charset=UTF-8");
  resp.getWriter().println(new String(URLReader.read("pl", "en", "koń")));
 }
}

当我运行它时,我得到:{"sentences"[{"trans":"end","orig":"koďż˝","translit":"","src_translit":""}],"src":"pl","server_time":30} 所以 utf 不能正常工作,但如果我返回编码的 url:http://translate.google.com/translate_a/t?client=o&text=ko%C5%84&hl=en&sl=pl&tl=en 并粘贴到 url 栏我得到正确:{"sentences":[{"trans":"horse","orig":"koń","translit":"","src_translit":""}],"dict":[{"pos":"noun","terms":["horse"]}],"src":"pl","server_time":76}

【问题讨论】:

    标签: java url encode utf


    【解决方案1】:
    byte[] bytes = json.getBytes("UTF-8");
    

    为您提供 UTF-8 字节序列,因此 URLReader.read 也为您提供 UTF-8 字节序列

    但您尝试在未指定编码器的情况下进行解码,即new String(URLReader.read("pl", "en", "koń")),因此 Java 将使用您的系统默认编码进行解码(不是 UTF-8)

    试试:

    new String(URLReader.read("pl", "en", "koń"), "UTF-8")
    

    更新

    这是我机器上完全可以运行的代码:

    public class URLReader {
    
        public static byte[] read(String from, String to, String string) {
            try {
                String text = "http://translate.google.com/translate_a/t?"
                        + "client=o&text=" + URLEncoder.encode(string, "UTF-8")
                        + "&hl=en&sl=" + from + "&tl=" + to + "";
                URL url = new URL(text);
                URLConnection conn = url.openConnection();
                // Look like faking the request coming from Web browser solve 403 error
                conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)");
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
                String json = in.readLine();
                byte[] bytes = json.getBytes("UTF-8");
                in.close();
                return bytes;
                //return text.getBytes();
            } catch (Exception e) {
                System.out.println(e);
                // becarful with returning null. subsequence call will return NullPointException.
                return null;
            }
        }
    }
    

    不要忘记将 ń 转义到 \u0144。 Java 编译器可能无法正确编译 Unicode 文本,因此最好以纯 ASCII 形式编写。

    public class AbcServlet extends HttpServlet {
    
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            resp.setContentType("text/plain;charset=UTF-8");
            byte[] read = URLReader.read("pl", "en", "ko\u0144");
            resp.getOutputStream().write(read) ;
        }
    }
    

    【讨论】:

    • hmm 现在返回 {"sentences":[{"trans":"end","orig":"ko�","translit":"","src_translit":""}] ,"src":"pl","server_time":20}
    • 是来自您的网络浏览器吗?在处理编码字节时不要使用 PrinWriter。 PrintWriter 将使用非 UTF-8 的 JVM 默认编码器。试试 getOutputStream.write((new String(URLReader.read("pl", "en", "koń"), "UTF-8") ).getBytes("UTF-8"))
    • 注意设置 resp.setContentType("text/plain;charset=UTF-8");并没有真正告诉您的 servlet 使用 UTF-8 对其进行编码。它只是通知目标 Web 浏览器/客户端您将发送一个用 UTF-8 编码的字节流。实际的内容编码不需要匹配内容类型标头。 (当然你不想要那个)
    • 我不需要写这个,我需要将正确的数据保存到数据库中,但我没有看到确定性的好方法
    • 我尝试了您的代码,但我从谷歌服务器收到 403 错误。它不允许我使用它的翻译器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 2015-07-29
    • 2019-07-06
    • 1970-01-01
    • 2013-06-01
    • 2018-08-21
    相关资源
    最近更新 更多