【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务;另外还可以使用Ajax调用WebService服务。

预备工作:开启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 ......");
    }
}

  生成源代码命令:

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

  可能出现的问题参考:http://blog.sina.com.cn/s/blog_924d6a570102w21v.html

  因为出现了上述问题,所以本次测试环境使用jdk 1.7

方法一:使用最简单、效率最高的方法调用WebService服务

  将生成的java文件包括文件夹直接导入项目,并使用其提供的API。

 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的。  

  

 

posted @ 2016-01-01 11:38  狂盗一枝梅  阅读(3227)  评论(0编辑  收藏  举报