【问题标题】:Protocol error trying to parse XML response in Java尝试在 Java 中解析 XML 响应的协议错误
【发布时间】:2021-11-22 14:28:11
【问题描述】:

我成功地进行了一个 API 调用,它是一个 SOAP 请求,正文中包含一个帐号。我使用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>"}​​​​​

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

【问题讨论】:

  • 1.不要将您的响应读入字符串(一般情况下,不要使用 StringBuffer,它在多年前已被 StringBuilder 取代)。将响应直接传递给 DocumentBuilder:Document xmlDom = docBuilder.parse(con.getInputStream()); 2. 您正在读取的响应不是 XML,而是 JSON。 "d" 对象属性的值似乎是一个 XML 文档,但您首先需要从 JSON 中提取该 XML。
  • 我现在收到异常,文件过早结束。我已经在消费这个流了吗? int responseCode = con.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader( con.getInputStream()));字符串输入线; StringBuffer 响应 = new StringBuffer (); while ((inputLine = in.readLine()) != null) { { sb.append(inputLine).append("\n"); xml2String = sb.toString(); in.close();
  • 好的,我能够解析出 JSON,因此我只剩下 XML,但我仍然收到无协议错误:异常,无协议: FirstNameStringTrueLastNameStringTrue BussFlds>TYPEStringTrue
  • 停止拨打docBuilder.parse(new InputSource(inputLine))。该构造函数将字符串视为 URI,而不是 XML 输入。
  • 我正在使用解析 json 的输出(这将输出减少到只是 XML): JSONObject json = new JSONObject(sb.toString()); jdata = json.getString("d"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();文档 xmlDom = docBuilder.parse(jdata);

标签: java xml parsing


【解决方案1】:

docBuilder.parse(new InputSource(inputLine))

您正在使用字符串缓冲区。用你的变量 xml2String 替换它

【讨论】:

    【解决方案2】:

    此回复:

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

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

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

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

    JSON“对象”基本上是一个带有字符串键的字典(即查找表)。您的回复只有一个条目,其键是"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 年历史的类,它是 Java 1.0 的一部分,它是为多线程使用而设计的,几乎不需要,而且会增加很多开销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-07
      • 2016-01-19
      • 2018-03-02
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多