ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java客户端调用SOAP方式的WebService服务实现方式分析 [打印本页]

作者: 伤心客    时间: 2024-8-27 17:26
标题: Java客户端调用SOAP方式的WebService服务实现方式分析
简介

   在多系统交互中,有时间需要以Java作为客户端来调用SOAP方式的WebService服务,本文通过分析不同的调用方式,以Demo的情势,资助读者在生产实践中选择合适的调用方式。
  本文JDK环境为JDK17。
  结论

   推荐利用Axis2或者Jaxws,以无客户端的情势来调用WebService。
  有客户端,推荐Maven插件。
  有客户端调用

主要时利用wsdl文档,自动生成对应的Java代码来实现
发起在pom文件中,配置对应的Maven插件来实现WebService客户端代码的自动生成。
JDK wsimport下令生成(不推荐)

简介
主要是利用jdk的自带工具wsimport工具实现,执行下令如下:
   wsimport -s C:\tmp\com -p com.example.demo5.wsdl -encoding utf-8 http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl
  优点
通常装有JDK的电脑或者服务器都可以直接运行,方便生成。
缺点
在现实的运用中wsimport下令会有很多标题,首先只有JDK1.8才支持这个下令,即使能利用,仍旧存在一些标题。其次,在JDK17以上没有自带这个工具,可能要安装插件才气利用,但是笔者安装了一些插件仍旧无法利用。
ApacheCXF自动生成(不推荐)

简介
ApacheCXF通过安装也可以自动生成对应的WebService客户端代码。具体操纵可见链接。
缺点
需要额外安装ApacheCXF插件。
Maven插件自动生成(推荐)

简介
通过spring.io网址的Demo示例,可以配置pom的maven插件,自动生成代码。
demo获取链接如下:
Getting Started | Consuming a SOAP web service (spring.io)
pom配置示比方下:
  1. <build>
  2.                 <plugins>
  3.                         <plugin>
  4.                                 <groupId>org.springframework.boot</groupId>
  5.                                 <artifactId>spring-boot-maven-plugin</artifactId>
  6.                         </plugin>
  7.                         <!-- tag::wsdl[] -->
  8.                         <plugin>
  9.                                 <groupId>com.sun.xml.ws</groupId>
  10.                                 <artifactId>jaxws-maven-plugin</artifactId>
  11.                                 <version>3.0.0</version>
  12.                                 <executions>
  13.                                         <execution>
  14.                                                 <goals>
  15.                                                         <goal>wsimport</goal>
  16.                                                 </goals>
  17.                                         </execution>
  18.                                 </executions>
  19.                                 <configuration>
  20.                                         <packageName>com.example.consumingwebservice.wsdl</packageName>
  21.                                         <wsdlUrls>
  22. <!--                                                <wsdlUrl>http://localhost:8080/ws/countries.wsdl</wsdlUrl>-->
  23.                                                 <wsdlUrl>http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl</wsdlUrl>
  24.                                         </wsdlUrls>
  25.                                         <sourceDestDir>${sourcesDir}</sourceDestDir>
  26.                                         <destDir>${classesDir}</destDir>
  27.                                         <extension>true</extension>
  28.                                 </configuration>
  29.                         </plugin>
  30.                         <!-- end::wsdl[] -->
  31.                 </plugins>
  32.         </build>
复制代码
生成代码如下:

调用方式:
  1. @RequestMapping(value = "/{ip}", method = RequestMethod.GET)
  2.     public ArrayOfString searchIp(@PathVariable("ip") String ip) {
  3.         IpAddressSearchWebServiceSoap ipAddressSearchWebServiceSoap = new IpAddressSearchWebService().getIpAddressSearchWebServiceSoap();
  4.         ArrayOfString response = ipAddressSearchWebServiceSoap.getCountryCityByIp(ip);
  5.         return response;
  6.     }
复制代码

优点
操纵简朴,改动小。
缺点
唯一的缺点,也是有客户端调用广泛存在的,自动生成代码后,需要重新部署一次。
Springboot集成Git插件实现

通过Springboot集成git插件,可以通过接口的情势来修改maven的wsdlUrls配置,然后推送到git服务,最后触发Jenkins自动部署。
以Git推送代码的情势来实当代码的自动生成,其缺点是,每次根据一份wsdl文件生成完代码,需要重启一次服务,但是笔者通过自动配置的情势可以做到一键部署。
此中触发Jenkins自动部署,可以通过git的配置实现,通过访问特定的url实现。配置好的git部署链接如下:
http://192.168.22.22:8080/job/demo_test/build?token=1987654567890hjkoijghfvgjjnmkjkmk
此中token的值可以自动定义,这样在借助代码的情势就可以做到一键部署。

实在当代码如下:
  1. package com.example.consumingwebservice;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.nio.file.Files;
  5. import java.nio.file.Path;
  6. import java.nio.file.Paths;
  7. import java.nio.file.StandardOpenOption;
  8. import java.util.Date;
  9. import org.apache.commons.logging.Log;
  10. import org.apache.commons.logging.LogFactory;
  11. import org.eclipse.jgit.api.Git;
  12. import org.eclipse.jgit.lib.Repository;
  13. import org.eclipse.jgit.transport.CredentialsProvider;
  14. import org.eclipse.jgit.transport.HttpConfig;
  15. import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
  16. public class GitUtil {
  17.     //private static Log log = LogFactory.getLog(GitUtil.class);
  18.     private GitUtil() {
  19.     }
  20.     public static Git getGit(String uri, CredentialsProvider credentialsProvider, String localDir) throws Exception {
  21.         Git git = null;
  22.         if (new File(localDir).exists() ) {
  23.             git = Git.open(new File(localDir));
  24.         } else {
  25.             git = Git.cloneRepository().setCredentialsProvider(credentialsProvider).setURI(uri)
  26.                     .setDirectory(new File(localDir)).call();
  27.         }
  28.         //设置一下post内存,否则可能会报错Error writing request body to server
  29.         git.getRepository().getConfig().setInt(HttpConfig.HTTP, null, HttpConfig.POST_BUFFER_KEY, 512*1024*1024);
  30.         return git;
  31.     }
  32.     public static CredentialsProvider getCredentialsProvider(String username, String password) {
  33.         return new UsernamePasswordCredentialsProvider(username, password);
  34.     }
  35.     public static Repository getRepository(Git git) {
  36.         return git.getRepository();
  37.     }
  38.     public static void pull(Git git, CredentialsProvider credentialsProvider) throws Exception {
  39.         git.pull().setRemote("origin").setCredentialsProvider(credentialsProvider).call();
  40.     }
  41.     public static void push(Git git, CredentialsProvider credentialsProvider, String filepattern, String message)
  42.             throws Exception {
  43.         git.add().addFilepattern(filepattern).call();
  44.         git.add().setUpdate(true);
  45.         git.commit().setMessage(message).call();
  46.         git.push().setCredentialsProvider(credentialsProvider).call();
  47.     }
  48.     public static void main(String[] args) throws Exception {
  49.         String uri = "http://192.168.9.11/test/webservice.git";
  50.         String username = "343535@qq.com";
  51.         String password = "xdfetrfrr";
  52.         CredentialsProvider credentialsProvider = getCredentialsProvider(username, password);
  53.         String localDir = "C:/tmp/git_test";
  54.         Git git = getGit(uri, credentialsProvider, localDir);
  55.         pull(git, credentialsProvider);
  56.         changeFile(localDir + "/pom.xml");
  57. //        push(git, credentialsProvider, ".", "提交文件");
  58.         push(git, credentialsProvider, "pom.xml", "修改pom文件" + new Date());
  59.     }
  60.     private static final String newText = "    <wsdlUrl>http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl</wsdlUrl>\r\n                    </wsdlUrls>";
  61.     protected static void changeFile(String filePath) {
  62.         try {
  63.             // 读取文本文件的内容
  64.             Path path = Paths.get(filePath);
  65.             String content = Files.readString(path);
  66.             System.out.println(content);
  67.             // 替换内容
  68.             String modifiedContent = content.replace("</wsdlUrls>", newText);
  69.             // 将修改后的内容写回文本文件
  70.             Files.write(path, modifiedContent.getBytes(), StandardOpenOption.WRITE);
  71.             System.out.println("文本文件内容已成功修改!");
  72.         } catch (IOException e) {
  73.             System.out.println("修改文本文件内容时出现错误:" + e.getMessage());
  74.         }
  75.     }
  76. }
复制代码
 如要实现流程图的规划,可以背景通过http的get哀求上文的git部署链接,实现接口的自动部署。
无客户端调用

也就是不需要按wsdl的格式来生成对应的Java代码,原理时通过构建xml的情势来访问WebService。
这里推荐利用Axis2或者Jaxws的方式来调用,二者各有优劣。
Axis调用(不推荐)

简介
通过pom引入axis依赖,实现无客户端访问,所需依赖如下:
   <dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
  代码实现如下:
  1. public static void main(String[] args){
  2.         try {
  3.             String nameSpac = "http://WebXml.com.cn/";
  4.             URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
  5.             QName sname = new QName(nameSpac, "MobileCodeWS");
  6.             QName pname = new QName(nameSpac, "MobileCodeWSSoap");
  7.             Service service = new Service( url, sname);
  8.             Call call = (Call)service.createCall(pname);
  9.             call.setSOAPActionURI(nameSpac + "getMobileCodeInfo");
  10.             call.setOperationName(new QName(nameSpac, "getMobileCodeInfo")); // 需要请求的方法
  11.             call.addParameter(new QName(nameSpac, "mobileCode"), XMLType.XSD_STRING, ParameterMode.IN);  // 入参
  12.             call.addParameter(new QName(nameSpac, "userID"), XMLType.XSD_STRING, ParameterMode.IN);  // 入参
  13. //            call.addParameter("param3", XMLType.SOAP_STRING, ParameterMode.IN);  // 入参
  14.             String param1 = "15932582632";  // 参数
  15.             String param2 = null;  // 参数
  16.             call.setReturnClass(String.class);  // 设置返回值
  17.             call.setUseSOAPAction(true);
  18.             Object invoke = call.invoke(new Object[]{param1, param2});// 调用获取返回值
  19. //            Object invoke =  call.invoke(new Object[]{});// 调用获取返回值
  20.             System.out.println(invoke);
  21.         }catch (Exception e){
  22.             e.printStackTrace();
  23.         }
  24.     }
复制代码
优点
较少的代码量,依赖需要少,实现简朴
缺点
通过笔者的实验,发现Axis的调用并不稳定,对于不同的接口,有的接口无参数调用可以调通,有参数调用会报错,有的接口有参数调用可以调通(如例),无参数调用会报错。
现实上,这个依赖在2006年便没有维护了,它的功能转移到了Axis2。
Axis2调用(推荐)

简介
通过pom引入axis2依赖,实现无客户端访问,所需依赖如下:
  1. <dependency>
  2. <groupId>org.apache.axis2</groupId>
  3. <artifactId>axis2-jaxws</artifactId>
  4. <version>1.7.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.axis2</groupId>
  8. <artifactId>axis2-adb-codegen</artifactId>
  9. <version>1.7.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.axis2</groupId>
  13. <artifactId>axis2-transport-local</artifactId>
  14. <version>1.7.0</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.apache.axiom</groupId>
  18. <artifactId>com.springsource.org.apache.axiom</artifactId>
  19. <version>1.2.5</version>
  20. </dependency>
复制代码
代码实现如下:
  1. import org.apache.axiom.om.OMAbstractFactory;
  2. import org.apache.axiom.om.OMElement;
  3. import org.apache.axiom.om.OMFactory;
  4. import org.apache.axiom.om.OMNamespace;
  5. import org.apache.axis2.AxisFault;
  6. import org.apache.axis2.addressing.EndpointReference;
  7. import org.apache.axis2.client.Options;
  8. import org.apache.axis2.client.ServiceClient;
  9. import org.apache.axis2.transport.http.impl.httpclient3.HttpTransportPropertiesImpl;
  10. /**
  11. *
  12. * @ClassName: MobileClientDoc
  13. * @Description: TODO
  14. * 方法二: 应用document方式调用 用ducument方式应用现对繁琐而灵活。现在用的比较多。因为真正摆脱了我们不想要的耦合
  15. * 即使用org.apache.axis2.client.ServiceClient类进行远程调用web服务,不生成客户端
  16. *
  17. * @date 2017年11月9日 下午1:27:17
  18. *
  19. */
  20. public class SoapAxis2Client {
  21.     private static String requestName = "getCountryCityByIp";
  22.     public static void ipWS() {
  23.         try {
  24.             ServiceClient serviceClient = new ServiceClient();
  25.             //创建服务地址WebService的URL,注意不是WSDL的URL
  26.             String url = "http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx";
  27.             EndpointReference targetEPR = new EndpointReference(url);
  28.             Options options = serviceClient.getOptions();
  29.             options.setTo(targetEPR);
  30.             //确定调用方法(wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合)
  31.             options.setAction("http://WebXml.com.cn/" + requestName);
  32.             //设置密码
  33.             HttpTransportPropertiesImpl.Authenticator auth = new HttpTransportPropertiesImpl.Authenticator();
  34. //            auth.setUsername(username);  //服务器访问用户名
  35. //            auth.setPassword(password); //服务器访问密码
  36. //            options.setProperty(HTTPConstants.AUTHENTICATE, auth);
  37.             OMFactory fac = OMAbstractFactory.getOMFactory();
  38.             /*
  39.              * 指定命名空间,参数:
  40.              * uri--即为wsdl文档的targetNamespace,命名空间
  41.              * perfix--可不填
  42.              */
  43.             OMNamespace omNs = fac.createOMNamespace("http://WebXml.com.cn/", "");
  44.             // 指定方法
  45.             OMElement method = fac.createOMElement(requestName, omNs);
  46.             // 指定方法的参数
  47.             OMElement theIpAddress = fac.createOMElement("theIpAddress", omNs);
  48.             theIpAddress.setText("111.249.198.56");
  49. //            OMElement userID = fac.createOMElement("userID", omNs);
  50. //            userID.setText("");
  51.             method.addChild(theIpAddress);
  52. //            method.addChild(userID);
  53.             method.build();
  54.             //远程调用web服务
  55.             OMElement result = serviceClient.sendReceive(method);
  56.             //值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。
  57.             String xml = result.cloneOMElement().toString();
  58.             System.out.println(xml);
  59.         } catch (AxisFault axisFault) {
  60.             axisFault.printStackTrace();
  61.         }
  62.     }
  63.     public static void main(String[] args) throws AxisFault {
  64.         ipWS();
  65.     }
  66. }
复制代码
优点
代码量较少,通过配置xml节点实现系统调用,可以设置灵活的调用方式。经过实验,对各种WebService接口的有参无参调用,都能取得精确的返回效果。
测试效果如下:
   <getCountryCityByIpResponse xmlns="http://WebXml.com.cn/"><getCountryCityByIpResult><string>111.249.198.56</string><string>台湾省  </string></getCountryCityByIpResult></getCountryCityByIpResponse>
  缺点
所需的pom配置文件较多,且引用不精确较难排查标题,且各个pom之间的版本冲突也需要解决。
Jaxws调用(推荐)

简介
引入对于的pom配置文件
  1. <dependency>
  2.    <groupId>org.apache.axis2</groupId>
  3.         <artifactId>axis2-jaxws</artifactId>
  4.         <version>1.7.0</version>
  5. </dependency>
复制代码
这里提前说下,下面代码大部分来自于csdn作者——LengYouNuan的文章,但是实在找不到对于作者了,提前声明。
还有它的原始代码并不能正常运行,会有服务器未能辨认 HTTP 头 SOAPAction 的值的报错,笔者通过实验和研究,添加了如下配置,才气正常运行:
   //这句话很重要,否则报错服务器未能辨认 HTTP 头 SOAPAction 的值
dispatch.getRequestContext().put(SOAPACTION_URI_PROPERTY, nameSpace + elementName);
dispatch.getRequestContext().put(SOAPACTION_USE_PROPERTY, true);
  由于利用的JDK17,对应的配置和以前不一样了:
  1. public interface BindingProvider {
  2.     String USERNAME_PROPERTY = "jakarta.xml.ws.security.auth.username";
  3.     String PASSWORD_PROPERTY = "jakarta.xml.ws.security.auth.password";
  4.     String ENDPOINT_ADDRESS_PROPERTY = "jakarta.xml.ws.service.endpoint.address";
  5.     String SESSION_MAINTAIN_PROPERTY = "jakarta.xml.ws.session.maintain";
  6.     String SOAPACTION_USE_PROPERTY = "jakarta.xml.ws.soap.http.soapaction.use";
  7.     String SOAPACTION_URI_PROPERTY = "jakarta.xml.ws.soap.http.soapaction.uri";
  8. ......
复制代码
应该主要是javax和jakarta的区别。
完整可运行代码如下:
  1. package com.example.consumingwebservice;
  2. import com.sun.xml.ws.client.BindingProviderProperties;
  3. import com.sun.xml.ws.developer.JAXWSProperties;
  4. import jakarta.xml.soap.*;
  5. import jakarta.xml.ws.Dispatch;
  6. import jakarta.xml.ws.Service;
  7. import org.w3c.dom.Document;
  8. import javax.xml.namespace.QName;
  9. import java.net.URL;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. import static jakarta.xml.ws.BindingProvider.SOAPACTION_URI_PROPERTY;
  13. import static jakarta.xml.ws.BindingProvider.SOAPACTION_USE_PROPERTY;
  14. /**
  15. * soap方式调用webservice方式客户端
  16. *
  17. * @author LengYouNuan
  18. * @create 2021-05-31 下午2:35
  19. */
  20. public class SoapJaxwsClient {
  21.     String nameSpace = ""; //wsdl的命名空间
  22.     String wsdlUrl = ""; //wsdl文档地址
  23.     String serviceName = ""; //服务的名字
  24.     String portName = "";
  25.     String responseName = ""; //@WebResult:注解上的name值
  26.     String elementName = ""; //默认是要访问的方法名 如果@WebMethod属性name有值 则是该值,实际还是以wsdl文档为主
  27.     int timeout = 20000;
  28.     /**
  29.      * @param nameSpace
  30.      * @param wsdlUrl
  31.      * @param serviceName
  32.      * @param portName
  33.      * @param element
  34.      * @param responseName
  35.      */
  36.     public SoapJaxwsClient(String nameSpace, String wsdlUrl,
  37.                            String serviceName, String portName, String element,
  38.                            String responseName) {
  39.         this.nameSpace = nameSpace;
  40.         this.wsdlUrl = wsdlUrl;
  41.         this.serviceName = serviceName;
  42.         this.portName = portName;
  43.         this.elementName = element;
  44.         this.responseName = responseName;
  45.     }
  46.     /**
  47.      * @param nameSpace
  48.      * @param wsdlUrl
  49.      * @param serviceName
  50.      * @param portName
  51.      * @param element
  52.      * @param responseName
  53.      * @param timeOut      毫秒
  54.      */
  55.     public SoapJaxwsClient(String nameSpace, String wsdlUrl,
  56.                            String serviceName, String portName, String element,
  57.                            String responseName, int timeOut) {
  58.         this.nameSpace = nameSpace;
  59.         this.wsdlUrl = wsdlUrl;
  60.         this.serviceName = serviceName;
  61.         this.portName = portName;
  62.         this.elementName = element;
  63.         this.responseName = responseName;
  64.         this.timeout = timeOut;
  65.     }
  66.     public String sendMessage(HashMap<String, String> inMsg) throws Exception {
  67.         // 创建URL对象
  68.         URL url = null;
  69.         try {
  70.             url = new URL(wsdlUrl);
  71.         } catch (Exception e) {
  72.             e.printStackTrace();
  73.             return "创建URL对象异常";
  74.         }
  75.         // 创建服务(Service)
  76.         QName sname = new QName(nameSpace, serviceName);
  77.         Service service = Service.create(url, sname);
  78.         // 创建Dispatch对象
  79.         Dispatch<SOAPMessage> dispatch = null;
  80.         try {
  81.             dispatch = service.createDispatch(new QName(nameSpace, portName), SOAPMessage.class, Service.Mode.MESSAGE);
  82.         } catch (Exception e) {
  83.             e.printStackTrace();
  84.             return "创建Dispatch对象异常";
  85.         }
  86.         // 创建SOAPMessage
  87.         try {
  88.             //这句话很重要,否则报错服务器未能识别 HTTP 头 SOAPAction 的值
  89.             dispatch.getRequestContext().put(SOAPACTION_URI_PROPERTY, nameSpace + elementName);
  90.             dispatch.getRequestContext().put(SOAPACTION_USE_PROPERTY, true);
  91.             SOAPMessage msg = MessageFactory.newInstance(
  92.                     SOAPConstants.SOAP_1_1_PROTOCOL).createMessage();
  93.             msg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");
  94.             SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
  95.             // 创建SOAPHeader(不是必需)
  96.             // SOAPHeader header = envelope.getHeader();
  97.             // if (header == null)
  98.             // header = envelope.addHeader();
  99.             // QName hname = new QName(nameSpace, "username", "nn");
  100.             // header.addHeaderElement(hname).setValue("huoyangege");
  101.             // 创建SOAPBody
  102.             SOAPBody body = envelope.getBody();
  103.             QName ename = new QName(nameSpace, elementName, "");
  104.             SOAPBodyElement ele = body.addBodyElement(ename);
  105.             // 增加Body元素和值
  106.             for (Map.Entry<String, String> entry : inMsg.entrySet()) {
  107.                 ele.addChildElement(new QName(nameSpace, entry.getKey()))
  108.                         .setValue(entry.getValue());
  109.             }
  110.             // 超时设置
  111.             dispatch.getRequestContext().put(BindingProviderProperties.CONNECT_TIMEOUT, timeout);
  112.             dispatch.getRequestContext().put(JAXWSProperties.REQUEST_TIMEOUT, timeout);
  113.             // 通过Dispatch传递消息,会返回响应消息
  114.             SOAPMessage response = dispatch.invoke(msg);
  115.             // 响应消息处理,将响应的消息转换为doc对象
  116.             Document doc = response.getSOAPPart().getEnvelope().getBody()
  117.                     .extractContentAsDocument();
  118.             String ret = doc.getElementsByTagName(responseName).item(0).getTextContent();
  119.             return ret;
  120.         } catch (Exception e) {
  121.             e.printStackTrace();
  122.             throw e;
  123.         }
  124.     }
  125.     public static void main(String[] args) throws Exception {
  126. //        SoapClient soapClient=new SoapClient("http://spring.io/guides/gs-producing-web-service","http://localhost:8080/ws/countries.wsdl",
  127. //                "CountriesPortService","CountriesPortSoap11","getCountry",
  128. //                "getCountryResponse",
  129. //                2000);
  130.         SoapJaxwsClient soapClient = new SoapJaxwsClient("http://WebXml.com.cn/", "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl",
  131.                 "MobileCodeWS", "MobileCodeWSSoap", "getDatabaseInfo",
  132.                 "getDatabaseInfoResponse",
  133.                 2000);
  134. //        SoapClient soapClient=new SoapClient("http://WebXml.com.cn/","http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.wsdl",
  135. //                "IpAddressSearchWebService","IpAddressSearchWebServiceSoap","getCountryCityByIp",
  136. //                "getCountryCityByIpResult",
  137. //                2000);
  138.         //封装请求参数
  139.         HashMap<String, String> msg = new HashMap<>();
  140. //        msg.put("theIpAddress","111.249.198.56");
  141. //        msg.put("mobileCode","18702750020");
  142. //        msg.put("userID","");
  143.         String s = soapClient.sendMessage(msg);
  144.         System.out.println(s);
  145.     }
  146. }
复制代码
测试效果:

优点
pom配置简朴,无须解决各种版本依赖的标题。
缺点
可以看到Jaxws的调用和Axis2一样,都具有较高的灵活性,都可以自定义xml的节点数据。
所不同的是,它的调用代码稍显繁琐,但如果在生产中,有良好的封装,这应该不是标题。
小结

对于SOAP方式WebService的调用,有客户端的调用,推荐maven插件自动生成代码的情势,唯一的缺点是需要重新部署一次。
对于无客户端的调用,推荐Axis2或者Jaxws的情势,考虑到二者实现实在各有优劣,有需要的读者可以自行甄别选用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4