java - XmlRpcClientException : An invalid XML character (Unicode: 0x8) was found

标签 java apache api xml-rpc bugzilla

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

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

最佳答案

已经晚了,但万一有人偶然发现了这个。

编辑:

我已经研究了两个月了,终于找到了解决上述问题的可行方法。

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

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

XmlRpcClientException: An invalid XML character (Unicode: 0x8) was found

要解决此问题,需要扩展 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 发送到parse 方法的InputSource

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

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 参数以及搜索条件的效用函数。

你会在某些特定值上得到这个异常让我们说 offsetxlimity您可以通过在 Debug模式下运行找到它。

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

这样您将一次提取一个错误并在 Debug模式下运行,您可以确定导致异常的确切错误。

对于 x = 21900y = 100 执行如下操作:

for(int i = 21900; i <= 22000; i++)
{
 result = ws.search(searchCriteria, i, 1);
}

在 Debug模式下运行它,我发现导致该错误的实际 偏移量21963,因此我编写了代码来避免该特定错误:

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];
 }
}

关于java - XmlRpcClientException : An invalid XML character (Unicode: 0x8) was found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6189166/

相关文章:

java - Groovy 类使用另一个实例字段

Java:使用 RestFB 获取 facebook 上的群组列表

java - 使用套接字 ID 的套接字详细信息

api - 在 Google Maps API 上显示 Shapefiles .shp 区域和标记?

rest - 如何在 Postman 中自动获取 token

java - 检查字符串数组的单词及其第一个字母

apache - Amazon EC2 和 Namecheap 域和子域设置?

Apache mod_session_dbd - 有人让它工作吗?

php - 多语言和 mod_rewrite

javascript - facebook graph api 图片