【Java EE 學習 80 下】【調用WebService服務的四種方式】【WebService中的註解】

不考慮第三方框架,若是隻使用JDK提供的API,那麼可使用三種方式調用WebService服務;另外還可使用Ajax調用WebService服務。javascript

預備工做:開啓WebService服務,使用jdk命令wsimport生成調用源代碼

package com.kdyzm.ws;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService
public class MyWsServer {
    public String calculate(int input){
        System.out.println("接收到請求數據:"+input);
        return input*input+"";
    }
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:9090/ws", new MyWsServer());
        System.out.println("server ready ......");
    }
}

  生成源代碼命令:html

wsimport -s . http://localhost:9090/ws?wsdl

  可能出現的問題參考:http://blog.sina.com.cn/s/blog_924d6a570102w21v.htmljava

  由於出現了上述問題,因此本次測試環境使用jdk 1.7node

方法一:使用最簡單、效率最高的方法調用WebService服務

  將生成的java文件包括文件夾直接導入項目,並使用其提供的API。ajax

 1 package com.kdyzm.call.method;
 2 
 3 import com.kdyzm.ws.MyWsServer;
 4 import com.kdyzm.ws.MyWsServerService;
 5 
 6 /**
 7  * 第一種方式就是使用wsimport命令獲取全部的須要調用的代碼,並直接使用這些代碼完成任務
 8  * @author kdyzm
 9  *
10  */
11 public class Method1 {
12     public static void main(String[] args) {
13         MyWsServerService myWsServerService=new MyWsServerService();
14         MyWsServer myWsServer=myWsServerService.getMyWsServerPort();
15         String result=myWsServer.calculate(2);
16         System.out.println(result);
17     }
18 }

  客戶端控制檯打印結果:4編程

  服務端控制檯打印結果:瀏覽器

  

  這種方式是使用最多的方式,也是最不容易出錯、效率最高的方式,推薦使用這種方式。服務器

方法二:使用URLConnection調用WebService服務

  URLConnection是JDK最底層的類,全部的網絡服務底層都要使用到該類,如今嘗試直接使用該類操做調用WebService服務的過程,可是首先須要獲取SOAL格式的請求體,可使用以前介紹的Web Service Explorer瀏覽器捕獲請求體,並將該請求體進行處理轉換成字符串的格式(對"進行轉義\")。網絡

  使用這種方法不依賴於任何服務端提供的類和接口,只須要知道SOAP請求體的內容便可。框架

  SOAL請求體:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:q0="http://ws.kdyzm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <q0:calculate>
            <arg0>2</arg0>
        </q0:calculate>
    </soapenv:Body>
</soapenv:Envelope>

  轉換成String字符串:

1 String requestMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
2                 + "xmlns:q0=\"http://ws.kdyzm.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
3                 + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soapenv:Body>" + "    <q0:calculate>"
4                 + "        <arg0>2</arg0>" + "    </q0:calculate>" + "</soapenv:Body>" + "</soapenv:Envelope>";

  測試代碼:

 1 package com.kdyzm.call.method;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.InputStream;
 5 import java.io.InputStreamReader;
 6 import java.io.OutputStream;
 7 import java.io.PrintWriter;
 8 import java.net.HttpURLConnection;
 9 import java.net.URL;
10 
11 /**
12  * 第二種方式是使用UrlConnecction調用WebService服務。
13  */
14 public class Method2 {
15     public static void main(String[] args) throws Exception {
16         // 服務的地址
17         URL url = new URL("http://localhost:9090/ws");
18 
19         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
20         connection.setDoInput(true);
21         connection.setDoOutput(true);
22 
23         connection.setRequestMethod("POST");
24         connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
25         OutputStream os = connection.getOutputStream();
26         PrintWriter pw = new PrintWriter(os, true);
27         String requestMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
28                 + "xmlns:q0=\"http://ws.kdyzm.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
29                 + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soapenv:Body>" + "    <q0:calculate>"
30                 + "        <arg0>2</arg0>" + "    </q0:calculate>" + "</soapenv:Body>" + "</soapenv:Envelope>";
31         // 發起請求
32         pw.println(requestMessage);
33 
34         InputStream is = connection.getInputStream();
35         BufferedReader br = new BufferedReader(new InputStreamReader(is));
36         String temp = null;
37 
38         System.out.println("響應結果是:");
39         while ((temp = br.readLine()) != null) {
40             System.out.println(temp);
41         }
42         pw.close();
43         os.close();
44         br.close();
45         is.close();
46     }
47 }

  結果和方法一種的結果相同。

方法三:使用JDK提供的WebService相關API實現對WebService的服務調用

  使用這種方法只須要一個接口:MyWsServer就能夠了,該接口也是經過wsimport命令獲取的,它和服務端對應的服務類同名。

 1 package com.kdyzm.call.method;
 2 
 3 import java.net.URL;
 4 
 5 import javax.xml.namespace.QName;
 6 import javax.xml.ws.Service;
 7 
 8 import com.kdyzm.ws.MyWsServer;
 9 
10 /**
11  * 第三種方式:經過客戶端編程實現Serice的遠程調用
12  * 使用這種方式只須要知道一個MyWsServer接口就能夠了。
13  * @author kdyzm
14  *
15  */
16 public class Method3 {
17     public static void main(String[] args) throws Exception {
18         URL url = new URL("http://localhost:9090/ws?wsdl");
19         Service service=Service.create(url, new QName("http://ws.kdyzm.com/", "MyWsServerService"));
20         MyWsServer myWsServer=service.getPort(new QName("http://ws.kdyzm.com/", "MyWsServerPort"),MyWsServer.class);
21         String result=myWsServer.calculate(2);
22         System.out.println(result);
23     }
24 }

  服務端和客戶端的控制檯打印結果同上。

方法四:使用Ajax調用WebService服務

  這裏使用原生的js來操做該過程:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="UTF-8">
 5 <title>Insert title here</title>
 6 <script type="text/javascript">
 7     function ajaxFunction() {
 8         var xmlHttp;
 9         try {
10             // Firefox, Opera 8.0+, Safari
11             xmlHttp = new XMLHttpRequest();
12         } catch (e) {
13             // Internet Explorer
14             try {
15                 xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
16             } catch (e) {
17 
18                 try {
19                     xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
20                 } catch (e) {
21                     alert("您的瀏覽器不支持AJAX!");
22                 }
23             }
24         }
25         return xmlHttp;
26     }
27 </script>
28 </head>
29 <body>
30     <div id="content"></div>
31     <!-- 第四種方式:使用ajax的方式請求調用WebService服務 -->
32     <script type="text/javascript">
33         var xmlHttp = ajaxFunction();
34         var wsUrl = "http://localhost:9090/ws"; 35         var requestMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
36             + "xmlns:q0=\"http://ws.kdyzm.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
37             + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
38                 + "<soapenv:Body>"
39                 + "    <q0:calculate>"
40                 + "        <arg0>2</arg0>"
41                 + "    </q0:calculate>"
42                 + "</soapenv:Body>"
43                 + "</soapenv:Envelope>";
44  xmlHttp.open("POST", wsUrl, true); 45  xmlHttp.setRequestHeader("Content-Type", "text/xml;charset=utf-8"); 46         xmlHttp.onreadystatechange = _callback;
47         xmlHttp.send(requestMessage);
48         function _callback() {
49             if (xmlHttp.readyState == 4) {
50                 if (xmlHttp.status == 200) {
51                     var retXml = xmlHttp.responseXML; 52                     var result = retXml.getElementsByTagName("return")[0];
53                     document.getElementById("content").innerHTML = result.firstChild.nodeValue;; 54                 }
55             }
56         }
57     </script>
58 </body>
59 </html>

  注意,result對象是[Object Element]類型的,須要調用.firstChild.nodeValue方法獲取文本值。

  使用這種方式只適合在IE瀏覽器中使用,使用谷歌瀏覽器或者火狐瀏覽器都失敗了,出現的異常狀況: xmlHttp.open("POST", wsUrl, true);這句代碼設置了請求方式是POST,可是實際上沒管用,請求方式變成了OPTION,statckOverFlow上有人解釋先使用OPTION的請求方式測試和服務器的連通性,而後才使用POST方式發送請求數據,因此服務器纔會報出:

  

  無論說法是否正確,該問題在這裏暫時無法解決,先存檔;在IE中運行正常:

  

  服務器控制檯打印結果同上。

 註解

  WebService的註解包括:@WebService,@WebMethod,@WebResult,@WebParam,具體使用方法見下圖

  還有一個最重要的註解,使用該註解可以將服務發佈爲符合SOAP1.2規範的WebService服務:

  @BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)

  客戶端使用SOAP1.1能夠正常調用服務端1.2的服務,可是反之則不行,因此最好將發佈的服務都作成SOAP1.2的。  

  

相關文章
相關標籤/搜索