问题描述
||
我正在使用Apache XML-RPC库从Bugzilla中获取错误。调用该服务,我收到异常:
org.apache.xmlrpc.client.XmlRpcclientException:无法解析服务器的响应:在文档的元素内容中发现了无效的XML字符(Unicode:0x8)。
有没有办法了解错误在哪里。我找到了一个错误的日期,这会导致错误。但是有很多。我可以打印收到的xml或使异常更精确吗?
解决方法
为时已晚,但万一有人偶然发现。
编辑:
我已经研究了两个月,终于找到了解决上述问题的可行方法。
发生此问题的原因是,有时Bugzilla :: Webservice在响应远程过程调用时会在XML响应中发送无效字符。
当Apache \的XML-RPC尝试解析该响应时,会出现以下错误:
XmlRpcClientException:发现无效的XML字符(Unicode:0x8)
为了解决此问题,需要扩展Apache \的XML-RPC客户端以在解析无效响应之前清除无效的XML字符。
在此处找到apache-xmlrpc的源代码作为Eclipse项目。 (导入此项目而不是jar文件)
为此,我们首先需要扩展
BufferedReader
类以替换任何无效的XML字符,然后再将其返回。
因此,添加/apache-xmlrpc-3.1.3-src/client/src/main/java/org/apache/xmlrpc/client/util/XMLBufferredReader.java
,如下所示:
package org.apache.xmlrpc.client.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
/**
* @author Ahmed Akhtar
*
*/
public class XMLBufferredReader extends BufferedReader
{
/**
* @param in
*/
public XMLBufferredReader(Reader in)
{
super(in);
}
@Override
public int read(char[] cbuf,int off,int len) throws IOException
{
int ret = super.read(cbuf,off,len);
for(int i = 0; i < ret; i++)
{
char current = cbuf[i];
if(!((current == 0x9) ||
(current == 0xA) ||
(current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)) ||
((current >= 0x10000) && (current <= 0x10FFFF))))
{
cbuf[i] = \'r\';
}
}
return ret;
}
}
稍后,我们需要将扩展的XMLBufferedReader
发送到parse
方法的InputSource
。
文件“ 7”中的功能“ 6”需要更改为:
protected Object readResponse(XmlRpcStreamRequestConfig pConfig,InputStream pStream) throws XmlRpcException
{
BufferedReader in = new XMLBufferredReader(new BufferedReader(new InputStreamReader(pStream,StandardCharsets.UTF_8)));
InputSource isource = new InputSource(in);
XMLReader xr = newXMLReader();
XmlRpcResponseParser xp;
try {
xp = new XmlRpcResponseParser(pConfig,getClient().getTypeFactory());
xr.setContentHandler(xp);
xr.parse(isource);
} catch (SAXException e) {
throw new XmlRpcClientException(\"Failed to parse server\'s response: \" + e.getMessage(),e);
} catch (IOException e) {
throw new XmlRpcClientException(\"Failed to read server\'s response: \" + e.getMessage(),e);
}
if (xp.isSuccess()) {
return xp.getResult();
}
Throwable t = xp.getErrorCause();
if (t == null) {
throw new XmlRpcException(xp.getErrorCode(),xp.getErrorMessage());
}
if (t instanceof XmlRpcException) {
throw (XmlRpcException) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new XmlRpcException(xp.getErrorCode(),xp.getErrorMessage(),t);
}
在对Apache \的XML-RPC客户端进行此扩展之后,一切都应该正常工作。
注意:本文的其余部分是我发布的初始解决方案,如果有人不想扩展Apache的XML-RPC客户端,这是一种解决方法。
旧帖子:
如果您使用的是Bugzilla :: Webservice :: Bug :: search实用程序函数,带有一些offset
和limit
参数以及搜索条件。
您可能会在某些特定值上遇到此异常,比如说ѭ9的x
和ѭ10的ѭ13by,您可以通过在调试模式下运行找到它们。
现在调用search
函数,方法是将x
保持为偏移量,将1
保持为limit
,然后循环并递增x
直到达到x + y
的值作为偏移量,同时仍将limit
保持为1
。
这样,您将一次提取一个错误并以调试模式运行,您可以确定导致异常的确切错误。
对于x = 21900
和y = 100
,请执行以下操作:
for(int i = 21900; i <= 22000; i++)
{
result = ws.search(searchCriteria,i,1);
}
在调试模式下运行此命令,我发现导致该错误的实际“ 9”是“ 27”,因此我编写了代码以避免该特定的错误:
if(offset != 21900)
{
result = obj.search(productNames,offset,limit);
bugsObj = (Object[])result.get(\"bugs\");
}
else
{
result = obj.search(productNames,21900,63);
Object[] bugsObj1 = (Object[])result.get(\"bugs\");
result = obj.search(productNames,21964,36);
Object[] bugsObj2 = (Object[])result.get(\"bugs\");
bugsObj = new Object[bugsObj1.length+bugsObj2.length];
for(int i = 0; i < bugsObj1.length + bugsObj2.length; i++)
{
bugsObj[i] = i < bugsObj1.length ? bugsObj1[i] : bugsObj2[i - bugsObj1.length];
}
}