xml 输出中的非拉丁字符
Posted
技术标签:
【中文标题】xml 输出中的非拉丁字符【英文标题】:nolatin characters in xml output 【发布时间】: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 输出它 【参考方案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) 进行编码和解码。
我相信您需要先致电setContentType 或setCharacterEncoding,然后再致电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>
ä
ü
å
</test>
得到:
<test>
ä
ü
å
</test>
也许不完全是你想要的,但一个很好的解决方法。您可以使用utf8-chartable.de 之类的网站来查找所需的值。
【讨论】:
这输出de字符很好,有没有办法将这些de字符转换成这些xml代码? 我的意思是有一个java api可以直接在java中进行转换吗? @unknown (google):没有 Java API 可以自动创建这些实体。有关如何执行此操作的示例,请参见此答案:***.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();
【讨论】:
以上是关于xml 输出中的非拉丁字符的主要内容,如果未能解决你的问题,请参考以下文章