我正在使用我自己的服務器上編譯的Apache mod_dav。我的客戶端是用Java構建的從頭開始的自定義HTTP解析代碼。我一直在使用這個服務器和代碼庫,在服務器上同步千兆字節的數據。Apache mod_dav XML尾隨內容Java中的SAX解析器錯誤
今天我遇到了一個從未出現的問題:可怕的SAX「內容不允許在尾部」錯誤。在整個服務器資源樹中執行WebDAV PROPFIND時,我總是在相同的位置出現此錯誤。
我測試並重新測試了我的HTTP解析代碼,但它非常簡單:Apache正在發送回分塊內容,並且塊指示要消耗的字節數。
它失敗的地方是恰好使用110塊的XML響應---比大多數其他響應(這是一個非常大的目錄)大得多。但是,在我的日誌中,我可以看到沒有「尾隨內容」 - 每個XML響應(產生錯誤,不響應)以簡單的換行符結束。
但更令人苦惱的是:我有一個輸入流,用於解析HTTP分塊內容並返回一個簡單的字節字符串。當我將此輸入流直接傳遞給XML解析器時,出現以下錯誤。但是,如果我採用相同的輸入流並從其中流出所有字節,請將它們放在ByteArrayInputStream中,然後將ByteArrayInputStream(應該包含完全相同的數據!)發送到解析器,不會發生錯誤!直接從輸入數據解析導致錯誤的是什麼?
我的XML解析器是非常簡單的:
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false);
沒有人見過這個? (我搜索「的mod_dav XML的錯誤」 ---和剛拿到無關bug我五年前提出。)
這裏是堆棧跟蹤的相關部分:
Cause:org.xml.sax.SAXParseException: Content is not allowed in trailing section.
com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
com.globalmentor.net.http.HTTPClientTCPConnection.readResponseBodyXML(HTTPClientTCPConnection.java:666)
com.globalmentor.net.http.webdav.WebDAVResource.propFind(WebDAVResource.java:453)
更新:我一遍又一遍地做了這個測試。最後,我添加了代碼走堆棧跟蹤並打印出SAX解析信息獲取:
Public Id: null System Id: null Line# 21937 Column# 1
我從日誌文件複製XML,果然,線21937是文件的結尾---但那裏什麼都沒有!