XmlRpcClientException:找到无效的XML字符(Unicode:0x8)

时间:2011-05-31 14:32:36

标签: java apache api xml-rpc bugzilla

我正在使用Apache XML-RPC库来获取Bugzilla的错误。调用该服务,我收到异常: org.apache.xmlrpc.client.XmlRpcClientException:无法解析服务器的响应:在文档的元素内容中找到了无效的XML字符(Unicode:0x8)。

有没有办法了解错误的确切位置。我找到了错误的日期,这会导致错误。但是他们中有很多。我可以打印收到的xml或使异常更精确吗?

1 个答案:

答案 0 :(得分:1)

迟到了,万一有人偶然发现了这一点。

修改

我已经在这两个月了,最后我找到了解决上述问题的可行方案。

出现此问题是因为Bugzilla::Webservice有时响应远程过程调用,会在XML响应中发送无效字符。

当Apache的XML-RPC尝试解析该响应时,它会出现以下错误:

  

XmlRpcClientException:找到了无效的XML字符(Unicode:0x8)

要解决此问题,需要扩展Apache的XML-RPC客户端,以便在尝试解析之前清除无效XML字符的响应。

apache-xmlrpc 的源代码作为Eclipse项目here查找。 (导入此项目而不是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发送到InputSource方法的parse

文件readResponse中的函数/apache-xmlrpc-3.1.3-src/client/src/main/java/org/apache/xmlrpc/client/XmlRpcStreamTransport.java需要更改为:

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实用程序功能包含一些offsetlimit参数以及搜索条件。

您将在某些特定值上获得此异常,例如x offsety limit,您可以通过在调试模式下运行找到它。< / p>

现在调用search函数,将x保留为偏移量,1保留为limit,然后循环并递增x,直到达到值{ {1}}作为偏移,同时仍将x + y保留为limit

通过这种方式,您将一次一个地提取错误并在调试模式下运行,您可以确定导致异常的确切错误。

1x = 21900执行以下操作:

y = 100

在调试模式下运行我发现导致该错误的实际for(int i = 21900; i <= 22000; i++) { result = ws.search(searchCriteria, i, 1); } offset所以我编写代码以避免该特定错误:

21963