试图解析 Java 中的 XML 响应的协议错误

Protocol error trying to parse XML response in Java

我成功地进行了 API 调用,这是一个 SOAP 请求,帐号在 body 中。我使用 Httpurlconnection 连接,我正在使用 BufferedReader:

读取这些结果
if (responseCode == HttpURLConnection.HTTP_OK) {​​​​​ // success
    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {​​​​​
    {​​​​​
        sb.append(inputLine).append("\n");
        String xml2String = sb.toString();

然后使用documentbuilderfactory构建文档以读入解析器:

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
Document xmlDom = docBuilder.parse(new InputSource(inputLine));

然后尝试解析:

DOMParser parser = new DOMParser();
parser.parse(new InputSource(new StringReader(returnList.item(0).getTextContent())));
Document doc = parser.getDocument();
NodeList responsedata = doc.getDocumentElement().getChildNodes();

NodeList returnList = xmlDom.getElementsByTagName("DATA");

// Get the DATA
DOMParser parser = new DOMParser();
parser.parse(new InputSource(new StringReader(returnList.item(0).getTextContent())));
Document doc = parser.getDocument();
NodeList responsedata = doc.getDocumentElement().getChildNodes();

这是我得到的错误(包括 API 请求的输出):

Exception,no protocol:
{​​​​​"d":"<DATA><BussFlds><FieldName>FirstName</FieldName><Value><![CDATA[TESTY]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>LastName</FieldName><Value><![CDATA[TESTER]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>TYPE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>DATE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>CUSTCODE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>PREMCODE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>ADDRESS</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>CITY</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>STATE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>ZIP</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>ZIP4</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>ACCTBALANCE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>PASTDUE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds><BussFlds><FieldName>PHONE</FieldName><Value><![CDATA[]]></Value><DataType>String</DataType><Format></Format><Editable>True</Editable></BussFlds></DATA>"}​​​​​

我怀疑是第一行的大括号数据或缺少 header 信息,但我不确定这是否是问题所在或如何解决。谢谢!

docBuilder.parse(new InputSource(inputLine))

您正在使用字符串缓冲区。将其替换为您的变量 xml2String

此回复:

{"d":"<DATA><BussFlds>…

不是XML。您无法 使用 DocumentBuilder 阅读它。

该响应的格式称为 JSON。您不能使用 XML 解析器来读取它。

因此,您需要将响应传递给 JSON 解析器, 而不是 XML 解析器。

一个JSON“对象”基本上是一个带有字符串键的字典(即查找table)。您的回复只有一个条目,其键为 "d"。所以你首先需要 parse the response as JSON:

String xml;
try (JsonParser jsonParser = Json.createParser(con.getInputStream())) {
    xml = jsonParser.getObject().getString("d");
}

(还有其他 JSON 解析库可用。我为上面的示例选择了 Java EE 的一部分。)

请注意,代码 不会 尝试先将 con.getInputStream() 作为字符串读取。这样做没有任何好处。解析器直接接受 InputStream。这意味着不需要使用 InputStreamReader、BufferedReader 或 StringBuffer。

现在 xml 变量中有 XML 内容,您可以使用 DocumentBuilder 对其进行解析:

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
Document xmlDom = docBuilder.parse(new InputSource(new StringReader(xml)));

旁注:您应该永远不要使用 StringBuffer。请改用 StringBuilder。 StringBuffer 是一个有 26 年历史的 class,它是 Java 1.0 的一部分,它是为多线程使用而设计的,这几乎从不需要,并且增加了很多开销。