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

      

  • 相关阅读:
    TCP和UDP的区别
    项目--华为商城---登录页面(一)
    Servlet(一)—— 文件上传(表单文件上传)
    LeetCode(一) —— 存在重复
    电脑右击不能创建txt文件
    边工作边刷题:70天一遍leetcode: day 92-2
    自底向上集成 Bottom-Up
    分层集成(线性关系) Layers
    基干集成(内核耦合度高) Backbone
    三明治集成(分而治之策略) 又分为传统型和改进型 Sandwich
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/5093124.html
Copyright © 2020-2023  润新知