簡體   English   中英

格式化Web服務響應

[英]Formatting Web Service Response

我使用以下函數來檢索Web服務響應:

private String getSoapResponse (String url, String host, String encoding, String soapAction, String soapRequest) throws MalformedURLException, IOException, Exception {         
    URL wsUrl = new URL(url);     
    URLConnection connection = wsUrl.openConnection();     
    HttpURLConnection httpConn = (HttpURLConnection)connection;     
    ByteArrayOutputStream bout = new ByteArrayOutputStream(); 

    byte[] buffer = new byte[soapRequest.length()];     
    buffer = soapRequest.getBytes();     
    bout.write(buffer);     
    byte[] b = bout.toByteArray();          

    httpConn.setRequestMethod("POST");
    httpConn.setRequestProperty("Host", host);

    if (encoding == null || encoding == "")
        encoding = UTF8;

    httpConn.setRequestProperty("Content-Type", "text/xml; charset=" + encoding);
    httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
    httpConn.setRequestProperty("SOAPAction", soapAction);

    httpConn.setDoOutput(true);
    httpConn.setDoInput(true);

    OutputStream out = httpConn.getOutputStream();
    out.write(b); 
    out.close();

    InputStreamReader is = new InputStreamReader(httpConn.getInputStream());
    StringBuilder sb = new StringBuilder();
    BufferedReader br = new BufferedReader(is);
    String read = br.readLine();

    while(read != null) {
        sb.append(read);
        read = br.readLine();
    }

    String response = decodeHtmlEntityCharacters(sb.toString());    

    return response = decodeHtmlEntityCharacters(response);
}

但是我對這段代碼的問題是它返回了許多特殊字符並使XML的結構無效。
響應示例:

<PLANT>A565</PLANT>
          <PLANT>A567</PLANT>
          <PLANT>A585</PLANT>
          <PLANT>A921</PLANT>
          <PLANT>A938</PLANT>
        </PLANT_GROUP>
      </KPI_PLANT_GROUP_KEYWORD>
      <MSU_CUSTOMERS/>
    </DU>
    <DU> 

所以為了解決這個問題,我使用下面的方法並傳遞整個響應來替換所有特殊字符及其相應的標點符號。

private final static Hashtable htmlEntitiesTable = new Hashtable();
static {
    htmlEntitiesTable.put("&","&");
    htmlEntitiesTable.put(""","\"");
    htmlEntitiesTable.put("&lt;","<");
    htmlEntitiesTable.put("&gt;",">");  
}

private String decodeHtmlEntityCharacters(String inputString) throws Exception {
    Enumeration en = htmlEntitiesTable.keys();

    while(en.hasMoreElements()){
        String key = (String)en.nextElement();
        String val = (String)htmlEntitiesTable.get(key);

        inputString = inputString.replaceAll(key, val);
    }

    return inputString;
}

但是出現了另一個問題。 如果響應包含此段&lt;VALUE&gt;&lt; 0.5 &lt;/VALUE&lt; &lt;VALUE&gt;&lt; 0.5 &lt;/VALUE&lt; 如果這將由方法評估,輸出將是:

<VALUE>< 0.5</VALUE>

這使得XML的結構再次失效。 數據是正確且有效的“<0.5”但是在VALUE元素中使用它會導致XML結構出現問題。

你能幫忙解決這個問題嗎? 也許我可以改進獲得或建立響應的方式。 有沒有更好的方法來調用和獲取Web服務的響應?

如何處理包含“<”或“>”的元素?

你知道如何使用第三方開源庫嗎?

你應該嘗試使用apache commons-lang:

StringEscapeUtils.unescapeXml(xml)

以下堆棧溢出帖子中提供了更多詳細信息:

如何在java中unescape XML

文檔:

http://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html http://commons.apache.org/proper/commons-lang/userguide.html#lang3

您使用SOAP錯誤。

特別是,您不需要以下代碼行:

     String response = decodeHtmlEntityCharacters(sb.toString());    

只需返回sb.toString() 為了$ DEITY的緣故,不要使用字符串方法來解析檢索到的字符串,使用XML解析器或完整的SOAP堆棧......

>或<字符是否始終出現在值的開頭? 然后你可以使用正則表達式來處理&gt;的情況。 或者&lt; 后跟一個數字(或點,就此而言)。

示例代碼,假設其中使用的替換字符串不會出現在XML中的任何其他位置:

private String decodeHtmlEntityCharacters(String inputString) throws Exception {
    Enumeration en = htmlEntitiesTable.keys();

    // Replaces &gt; or &lt; followed by dot or digit (while keeping the dot/digit)
    inputString = inputString.replaceAll("&gt;(\\.?\\d)", "Valuegreaterthan$1");
    inputString = inputString.replaceAll("&lt;(\\.?\\d)", "Valuelesserthan$1");

    while(en.hasMoreElements()){
        String key = (String)en.nextElement();
        String val = (String)htmlEntitiesTable.get(key);

        inputString = inputString.replaceAll(key, val);
    }

    inputString = inputString.replaceAll("Valuelesserthan", "&lt;");
    inputString = inputString.replaceAll("Valuegreaterthan", "&gt;");

    return inputString;
}

請注意,最合適的答案(對每個人來說都更容易)是在發送方正確編碼XML(這也會使我的解決方案無法使用BTW)。

很難應對所有情況,但是你可以通過假設任何少於空格的數據是數據來添加更多規則來覆蓋最常見的規則,並且大於它的前面有一個空格是數據,需要再次編碼。

private final static Hashtable htmlEntitiesTable = new Hashtable();
static {
    htmlEntitiesTable.put("&amp;","&");
    htmlEntitiesTable.put("&quot;","\"");
    htmlEntitiesTable.put("&lt;","<");
    htmlEntitiesTable.put("&gt;",">");  
}

private String decodeHtmlEntityCharacters(String inputString) throws Exception {
    Enumeration en = htmlEntitiesTable.keys();

    while(en.hasMoreElements()){
        String key = (String)en.nextElement();
        String val = (String)htmlEntitiesTable.get(key);

        inputString = inputString.replaceAll(key, val);
    }

    inputString = inputString.replaceAll("< ","&lt; ");       
    inputString = inputString.replaceAll(" >"," &gt;");       

    return inputString;
}

“>”未在XML中轉義。 所以你不應該有這個問題。 關於'<',以下是我能想到的選項。

  1. 在Web響應中對包含特殊字符的文本使用CDATA。
  2. 通過撤消訂單重寫文本。 例如。 如果是<2,則將其更改為2> x。 '>'除非是CDATA的一部分,否則不會被轉義。
  3. 使用XML響應中的其他屬性或元素來指示“<”或“>”。
  4. 使用正則表達式查找以“<”開頭並后跟字符串的序列,后跟結束標記的“<”。 並將其替換為您可以在以后解釋和替換的某些代碼或某些值。

此外,您不需要這樣做:

String response = decodeHtmlEntityCharacters(sb.toString()); 

在處理完文本中的“<”符號后,您應該能夠解析XML。

您可以使用站點來測試正則表達式。

為什么不序列化你的xml?它比你正在做的容易得多。

舉個例子:

var ser = new XmlSerializer(typeof(MyXMLObject));
using (var reader = XmlReader.Create("http.....xml"))
{
     MyXMLObject _myobj = (response)ser.Deserialize(reader);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM