2013-11-20 117 views
1

我很新SOAP WebService開發Java我有以下問題。如何在Java中爲此WS創建SOAP請求信封?

我有一個公開2種方法Web服務,第一個(即簡單)已經實現(通過其他人),並命名爲getVersion(),並且在了SoapUI有以下要求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <tem:getVersion/> 
    </soapenv:Body> 
</soapenv:Envelope> 

然後我有exeute在調用Web服務,並在I類有以前的web服務方法跟隨着方法的Java項目:

公共字符串getVersion(){ java.net.URL中的URL = NULL ; java.net.URLConnection conn = null;

java.io.BufferedReader rd = null; 
String soapResponse = ""; 

String risultato = ""; 

// SOAP ENVELOP for the request: 
String soapRequest; 
soapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" + "<soapenv:Header/>" + "<soapenv:Body> " + "<tem:getVersion/>" + "</soapenv:Body>" + "</soapenv:Envelope>"; 

try { 

    // Try to open a connection 
    url = new java.net.URL(_webServiceUrl); 
    conn = url.openConnection(); 

    // Set the necessary header fields 
    conn.setRequestProperty("SOAPAction", "http://tempuri.org/IMyService/getVersion"); 
    conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); 
    conn.setDoOutput(true); 

    // Send the request: 
    java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(conn.getOutputStream()); 
    wr.write(soapRequest); 
    wr.flush(); 
    // Read the response 
    rd = new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream())); 

    // Put the entire response into the soapResponse variable: 
    String line; 
    while ((line = rd.readLine()) != null) { 
     //System.out.println(line); 
     soapResponse = soapResponse + line + System.getProperty("line.separator"); 
    } 

    rd.close(); 

    // elaboro la risposta 
    SAXBuilder builder = new SAXBuilder(); 

    org.jdom.Document documentXML = null; 
    documentXML = builder.build(new StringReader(soapResponse)); 

    XPath xPath; 
    Element objectElement; 
    //xPath = XPath.newInstance("s:Envelope/s:Body/getVersionResponse/getVersionResult"); 
    xPath = XPath.newInstance("s:Envelope/s:Body"); 
    xPath.addNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/"); 

    objectElement = (Element) xPath.selectSingleNode(documentXML); 

    if (objectElement != null) { 
     risultato = objectElement.getValue(); 
    } 

} catch (Exception ex) { 
    ex.printStackTrace(); 
} 

return risultato; 

}

現在我必須複製創建一個新的方法(在調用WS方法的Java項目)的第二種方法同樣的事情(這是比較複雜的,因爲,不像以前的一個,需要傳遞一些參數),我對此有些懷疑。

因此,情況是以下之一:在了SoapUI有一個名爲getConfigSettings這個WS方法和要求是:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
     <soapenv:Header/> 
     <soapenv:Body> 
      <tem:getConfigSettings> 
      <!--Optional:--> 
      <tem:login>?</tem:login> 
      <!--Optional:--> 
      <tem:password>?</tem:password> 
      <!--Optional:--> 
      <tem:ipAddress>?</tem:ipAddress> 
      <!--Optional:--> 
      <tem:clientVersion>?</tem:clientVersion> 
      <!--Optional:--> 
      <tem:lastUpdateTime>?</tem:lastUpdateTime> 
      </tem:getConfigSettings> 
     </soapenv:Body> 
    </soapenv:Envelope> 

As you can see it requires some parameters (in SoapUi I have to replace characters with the correct parameter value) 

所以,在Java項目中,我創建了下面的方法執行這個呼籲我的要求創建SOAP信封(但我有關於它的正確性許多doubtsa)

public String authentication(String login, String password, String ipAddress, String clientVersion) { 


     java.net.URL url = null; 
     java.net.URLConnection conn = null; 

     java.io.BufferedReader rd = null; 
     String myResponse = ""; 
     String soapXml; 

     // SOAP ENVELOP for the request: 
     //soapXml = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"> " + "<s:Header>" + "<Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://tempuri.org/IMyService/getVersion</Action>" + "</s:Header>" + "<s:Body>" + "<getVersion xmlns=\"http://tempuri.org/\" />" + "</s:Body>" + "</s:Envelope>"; 
     soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" 
        + "<soapenv:Header/>" 
         + "<soapenv:Body> " 
          + "<tem:login>" + login + "</tem:login>" 
          + "<tem:password>" + password + "</tem:password>" 
          + "<tem:ipAddress>" + ipAddress + "</tem:ipAddress>" 
         + "</soapenv:Body>" 
        + "</soapenv:Envelope>"; 
........................................................ 
........................................................ 
........................................................ 
DO SOME OTHER STUFF 
........................................................ 
........................................................ 
........................................................ 
} 

正如你可以看到我已經創造了這個SOAP在我所插入的參數外型對我的要求recived作爲方法的輸入參數:

soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" 
       + "<soapenv:Header/>" 
        + "<soapenv:Body> " 
         + "<tem:login>" + login + "</tem:login>" 
         + "<tem:password>" + password + "</tem:password>" 
         + "<tem:ipAddress>" + ipAddress + "</tem:ipAddress>" 
        + "</soapenv:Body>" 
       + "</soapenv:Envelope>"; 

它是正確的還是我採取了錯誤的解決辦法?一些建議?

TNX

安德烈

回答

0

你的方法看起來簡單的,但你需要XML轉義要插入的字符串。

否則,如果字符串包含保留的XML字符(如<),則接收方可能不會解析您的請求。只是用</tem:login>作爲他的密碼:)

庫,如番石榴或Apache公地包含XML逃生考慮別人,看到這個線程指針: Best way to encode text data for XML in Java?

或者,你可以只包括你自己:

public static String xmlEscape(String s) { 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < sb.length(); i++) { 
    char c = s.charAt(i); 
    if ("<&\">'".indexOf(c) != -1) { 
     sb.append("&#" + ((int) c) + ";"); 
    } else { 
     sb.append(c); 
    } 
    } 
    return sb.toString(); 
} 

所以個夠代碼將類似於此:

soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" 
      + "<soapenv:Header/>" 
       + "<soapenv:Body> " 
        + "<tem:login>" + xmlEscape(login) + "</tem:login>" 
        + "<tem:password>" + xmlEscape(password) + "</tem:password>" 

PS 。切勿以明文形式通過網絡發送登錄數據!您可能希望使用https而不是http爲您的服務。