2011-05-31 122 views
2

我正在使用Apache XML-RPC庫從Bugzilla獲取錯誤。調用該服務時,我收到異常: org.apache.xmlrpc.client.XmlRpcClientException:無法解析服務器的響應:在文檔的元素內容中找到無效的XML字符(Unicode:0x8)。XmlRpcClientException:發現無​​效的XML字符(Unicode:0x8)

有什麼方法可以瞭解到底發生了什麼錯誤。我找到了錯誤的日期,這會導致錯誤。但是有很多。我可以打印收到的XML或更精確的例外嗎?

+1

看看這個:http://stackoverflow.com/questions/2358522/char-0x8-what-c​​haracter-is-this – 2011-05-31 14:39:54

+0

嗨,謝謝,我不知道它是退格,但如何得到答覆作爲一個字符串或得到這個角色的確切位置? – damluar 2011-05-31 15:37:09

+0

這是一個在bugzilla.mozilla.org [這裏](https://bugzilla.mozilla.org/show_bug.cgi?id=839023)上報告的錯誤。 – 2016-05-23 18:52:55

回答

1

它的晚,但萬一有人絆倒這一點。

編輯:

我一直在這兩個月了,終於我找到了一個可行的解決上述問題。

出現此問題的原因是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

功能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參數。

你會得到一些特定的值這個例外讓說的offsetxlimity您可以通過運行在調試模式找出來。

現在通過保持x膠印和1作爲limit,然後循環調用search功能,並增加x直至達到x + y值作爲偏移,同時仍保持limit1

這樣,您將一次提取一個錯誤並以調試模式運行,您可以確定導致異常的確切錯誤。

對於x = 21900y = 100做這樣的事情:

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

運行這在調試模式下,我發現,實際offset導致錯誤是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]; 
} 
}