Pages

2017年6月20日 星期二

Android SOAP client

這次的問題需要使用 soap 格式來和 WSDL server 連線傳遞資訊。因為 Android 沒有支援 soap 的 library 所以需要額外掛載支援 soap 的 Ksoap2 jar。
但是試過 Ksoap2 後發現它包出來的格式和WSDL的格式無法符合,讓server 無法解析。在<soapenv:Envelope>中無法自訂自己的namespace資訊。所以只能自己動手包出request,以下詳細說明各段所需程式碼。
基本所需的變數
private final String MAIN_REQUEST_URL = "http://tmpuri.org/";
private final String NAMESPACE = "http://namespaceuri.org/";
private String SOAP_ACTION = "http://namespaceurimethod.org/";
private HttpURLConnection SERVER_CONNECTION;

此request範例是我遇到的 WSDL server內定的格式,所以可能會跟別人遇到的有點誤差,自行調整
request範例
String requestString = "<Request>"+
    "<Access/>"+
    "<RequestContent>"+
    "<Parameter>"+
    "<Record>"+
    "<Field name=\"user\" value=\"hello\" />"+
    "<Field name=\"pwd\" value=\"abc1234\" />"+
    "</Record>"+
    "</Parameter>"+
    "<Document />"+
    "</RequestContent>"+
    "</Request>";
String actionName = "CheckLogin";

包出SOAP格式
public String getSoapEnvelope(String actionName, String requestString) {
    SOAP_ACTION += actionName;
    String soapEnvelope = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:sv=\""+NAMESPACE+"\">" +
               "<soapenv:Header/>" +
               "<soapenv:Body>";
    soapEnvelope += " <tip:"+actionName+"><sv:request>";
    //add request
    soapEnvelope += requestString;
    soapEnvelope += "</sv:request></sv:"+actionName+">";
    soapEnvelope += "</soapenv:Body></soapenv:Envelope>";
    return soapEnvelope;
}

包出soap envolope後,就可以把這個字串透過http request傳送給server
建立http request
public String sendRequestToSystem(String soapEnvelope) {
    BufferedReader rd = null;
    String line;
    String resultXML = "";
    try {
 //create connection
        URL url = new URL(MAIN_REQUEST_URL);
        HttpURLConnection soapServerConnection = (HttpURLConnection) url.openConnection();
        soapServerConnection.setDoOutput(true);
        soapServerConnection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
        soapServerConnection.setRequestProperty("SOAPAction", SOAP_ACTION);
        soapServerConnection.setRequestProperty("POST", MAIN_REQUEST_URL+" HTTP/1.1");
        soapServerConnection.setRequestProperty("Content-Length", "" + soapEnvelope.length());
        soapServerConnection.setRequestProperty("Accept-Encoding", "gzip,deflate");
        soapServerConnection.setRequestMethod("POST");
        byte[] postData = soapEnvelope.getBytes();
        //send data to soap server
        DataOutputStream wr = new DataOutputStream(this.soapServerConnection.getOutputStream());
        wr.write(postData);
        wr.close();
        //read data from soap server
        BufferedReader rd = new BufferedReader(new java.io.InputStreamReader(soapServerConnection.getInputStream()));
        while ((line = rd.readLine()) != null) {
     line = line.replace("&lt;", "<");
     line = line.replace("&gt;", ">");
     resultXML += line;
 }
    } catch (MalformedURLException e) {
 e.printStackTrace();
    } catch (ProtocolException e) {
 e.printStackTrace();
    } catch (IOException e) {
 e.printStackTrace();
    } catch (Exception e) {
 e.printStackTrace();
    }
    return resultXML;       
}

依照上述流程透過 resultXML變數就可以取得 soap response資訊
推薦一個測試WSDL的工具: SOAP UI
可以建立一個WSDL的project連線到server 測試每個request 很方便.

沒有留言:

張貼留言

 
 
Blogger Templates