9

以下の関数を使用して、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;これがメソッドによって評価される場合、出力は次のようになります。

<VALUE>< 0.5</VALUE>

これにより、XML の構造が再び無効になります。データは正しく有効な "< 0.5" ですが、それを VALUE 要素内に含めると、XML の構造に問題が発生します。

これに対処する方法を教えてください。たぶん、応答を取得または構築する方法が改善される可能性があります。Web サービスから呼び出して応答を取得するより良い方法はありますか?

「<」または「>」を含む要素をどのように処理できますか?

4

6 に答える 6

3

SOAP の使い方が間違っています。

特に、次のコード行は必要ありません。

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

戻るだけsb.toString()です。そして、$DEITY のために、文字列メソッドを使用して取得した文字列を解析したり、XML パーサーを使用したり、本格的な SOAP スタックを使用したりしないでください...

于 2013-10-29T17:46:42.620 に答える
1

> または < 文字は常に値の先頭に表示されますか? 次に、正規表現を使用して、 > のケースを処理できます。または <; その後に数字 (またはドット) が続きます。

サンプル コードでは、使用されている置換文字列が 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 にもなります)。

于 2013-10-28T18:52:51.293 に答える
0

xml をシリアル化してみませんか?、それはあなたがしていることよりもはるかに簡単です。

例として:

var ser = new XmlSerializer(typeof(MyXMLObject));
using (var reader = XmlReader.Create("http.....xml"))
{
     MyXMLObject _myobj = (response)ser.Deserialize(reader);
}
于 2013-10-30T01:18:01.993 に答える