【问题标题】:nolatin characters in xml outputxml 输出中的非拉丁字符
【发布时间】:2010-12-12 02:06:10
【问题描述】:

编辑:我硬编码了字符并使用repsonse writer来编写它,它仍然是 克尼斯堡

response.setCharacterEncoding("UTF-8"); response.setContentType(contentType); //if(contentType!=null)response.setHeader("Content-Type",contentType); Writer writer = response.getWriter();//new OutputStreamWriter(response.getOutputStream(),"UTF-8"); System.err.println("字符编码为"+response.getCharacterEncoding()); writer.write("柯尼斯堡"); writer.flush();

编辑: 我在调用 getWriter() 之前尝试了 setContentType 和 setContentEncoding,输出仍然没有区别:

如果(res.length()> 0){ //pw.write(res); response.setCharacterEncoding("UTF-8"); response.setContentType(contentType); //if(contentType!=null)response.setHeader("Content-Type",contentType); Writer writer = response.getWriter();//new OutputStreamWriter(response.getOutputStream(),"UTF-8"); System.err.println("字符编码为"+response.getCharacterEncoding()); writer.write(res); writer.flush(); }

我正在阅读一些德语字符,然后从 java servlet 以 xml 格式输出它们, 这是我用 UTF8 读取它们的方式:

国际长度=0; 字节[]缓冲区=新字节[1024]; 输出流 os = sock.getOutputStream(); InputStream 是 = sock.getInputStream(); 查询 += "\r\n"; os.write(query.getBytes("UTF8"));//iso8859_1")); 做{ len = is.read(buffer); 如果(长度> 0){ if(outstring==null)outstring=new StringBuffer(); outstring.append(new String(buffer,0,len, "UTF8")); } }while(len>0); System.out.println(outstring);

System.out 正确输出字符串: 柯尼斯堡

但是,当我也使用 charset=UTF-8 从我的 servletResponse 重新传输此字符串时 它变得狼吞虎咽:K�nigsberger

private void outputResponse(String res, HttpServletRequest 请求, HttpServletResponse 响应)抛出 IOException { 字符串 outputFormat = getOutputFormat(request); 字符串内容类型=空; PrintWriter pw = response.getWriter(); //response.setCharacterEncoding("UTF-8"); System.err.println("输出"+res); 内容类型=“文本/xml;字符集=UTF-8”; res="" + res; if(contentType!=null)response.setHeader("Content-Type",contentType); 如果(res.length()> 0){ pw.write(res); } pw.flush(); }

【问题讨论】:

  • 指定操作系统/平台。什么是“repipe”以及如何“repipe”?
  • os 是窗口。通过 repipe 我只是指从 Servlet 输出它

标签: xml utf-8


【解决方案1】:
do{
  len = is.read(buffer);
  if (len>0) { 
    if(outstring==null) outstring=new StringBuffer();
    outstring.append(new String(buffer,0,len, "UTF8"));
  }
}while(len>0);

这不是解码 UTF-8 的好方法,因为字符可能会在缓冲区边界上损坏 (details here)。 UTF-8 是一种可变宽度编码,因此字符需要一到四个字节来存储。如果它起作用了,那你就走运了。最好使用 Reader/Writer 类 (details here) 进行编码和解码。

我相信您需要先致电setContentTypesetCharacterEncoding,然后再致电getWriter。我觉得直接打电话给setHeader是不够的。


此 servlet 代码将正确编码示例字符串并将其作为 UTF-8 数据传输:

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/xml; charset=UTF-8");
    PrintWriter pw = response.getWriter();
    pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    pw.write("<data>K\u00F6nigsberger</data>");
    pw.flush();
    pw.close();
  }

请注意,我使用转义序列 \u00F6 来发出字符 U+00F6 (ö) 以确保我不会在我的文本编辑器中或在编译过程中损坏字符( see here for more details)。

数据是否可能在客户端被误解?使用十六进制编辑器检查输出。

编码为UTF-8,"K\u00F6nigsberger"应该变成字节序列:

4b c3 b6 6e 69 67 73 62 65 72 67 65 72

...字符 U+00F6 (ö) 变为 c3 b6。您可以使用这样的代码来检查您的值:

  public static void main(String[] args) throws IOException {
    String konigsberger = "K\u00F6nigsberger";
    dumpHex(System.out, konigsberger.getBytes("UTF-8"));
  }

  private static void dumpHex(PrintStream out, byte[] data) {
    for (byte b : data) {
      out.format("%02x ", b);
    }
    out.println();
  }

【讨论】:

  • 我怀疑这是一个 xml 格式问题,而不是 unicode 编码。我使用了代码 pw.write("K\u00F6nigsberger");当我在浏览器中查看它时,字符仍然被损坏......
【解决方案2】:

您应该按照示例并让 servlet response 了解要遵循的结束编码:

response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
ServletOutputStream out =response.getOutputStream();
out.write(output.getBytes("UTF-8"));    

【讨论】:

    【解决方案3】:

    你总是可以使用这样的实体:

    <test>
    &#228;
    &#252;
    &#229;
    </test>
    

    得到:

    <test>
    ä
    ü
    å
    </test>
    

    也许不完全是你想要的,但一个很好的解决方法。您可以使用utf8-chartable.de 之类的网站来查找所需的值。

    【讨论】:

    • 这输出de字符很好,有没有办法将这些de字符转换成这些xml代码?
    • 我的意思是有一个java api可以直接在java中进行转换吗?
    • @unknown (google):没有 Java API 可以自动创建这些实体。有关如何执行此操作的示例,请参见此答案:stackoverflow.com/questions/1273986/…
    • 我不确定,是否有图书馆。 Commons lang StringEscapeUtils 怎么样。有一个 escapeXml 方法,看起来很有希望:commons.apache.org/lang/api/org/apache/commons/lang/…
    【解决方案4】:

    我也遇到了同样的问题。我刚刚做了以下事情,它工作正常:

    byte[] k =xml.getBytes(UTF8_CHARSET); // xml is the string with unicode content.  getBytes("UTF-16") encodes given String into a sequence of bytes and returns an array of bytes. you can use xml.getBytes(UTF-16); for utf-16 encoding
    
    response.setContentType("text/xml");
    response.setContentLength(k.length);
    response.getOutputStream().write(k);
    response.getOutputStream().flush();
    response.getOutputStream().close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多