1、WebService 是一種跨編程語言和跨操作系統平台的遠程調用技術。
2、WebService平台的三大技術:XML+XSD,SOAP,WSDL。
1)、XML+XSD:WebService采用HTTP協議傳輸數據,采用XML格式封裝數據(即XML中說明調用遠程服務對象的哪個方法,傳遞的參數是什么,以及服務對象的 返回結果是什么)。XML是WebService平台中表示數據的格式。除了易於建立和易於分析外,XML主要的優點在於它既是平台無關的,又是廠商無關 的。無關性是比技術優越性更重要的:軟件廠商是不會選擇一個由競爭對手所發明的技術的。
2)、SOAP:WebService通過HTTP協議發送請求和接收結果時,發送的請求內容和結果內容都采用XML格式封裝,並增加了一些特定的HTTP消息頭,以說明 HTTP消息的內容格式,這些特定的HTTP消息頭和XML內容格式就是SOAP協議。SOAP提供了標准的RPC方法來調用Web Service。SOAP協議 = HTTP協議 + XML數據格式
。
3)、WSDL:WebService也一樣,WebService客戶端要調用一個WebService服務,首先要有知道這個服務的地址在哪,以及這個服務里有什么方 法可以調用,所以,WebService務器端首先要通過一個WSDL文件來說明自己家里有啥服務可以對外調用,服務是什么(服務中有哪些方法,方法接受 的參數是什么,返回值是什么),服務的網絡地址用哪個url地址表示,服務通過什么方式來調用。WSDL(Web Services Description Language)就是這樣一個基於XML的語言,用於描述Web Service及其函數、參數和返回值。它是WebService客戶端和服務器端都 能理解的標准格式。因為是基於XML的,所以WSDL既是機器可閱讀的,又是人可閱讀的,這將是一個很大的好處。一些最新的開發工具既能根據你的 Web service生成WSDL文檔,又能導入WSDL文檔,生成調用相應WebService的代理類代碼。
3、這里使用的是maven依賴,修改pom.xml配置文件,如下所示:
說明:這里使用springboot2.1.3或者2.2.4.RELEASE都可以,更高版本未測試。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 5 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 6 <modelVersion>4.0.0</modelVersion> 7 <parent> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-parent</artifactId> 10 <version>2.1.3.RELEASE</version> 11 <relativePath /> <!-- lookup parent from repository --> 12 </parent> 13 <groupId>com.example</groupId> 14 <artifactId>demo</artifactId> 15 <version>0.0.1-SNAPSHOT</version> 16 <name>demo</name> 17 <description>Demo project for Spring Boot</description> 18 19 <properties> 20 <java.version>1.8</java.version> 21 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> 22 </properties> 23 24 <dependencies> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-web</artifactId> 28 </dependency> 29 30 <dependency> 31 <groupId>org.springframework.boot</groupId> 32 <artifactId>spring-boot-starter-test</artifactId> 33 <scope>test</scope> 34 <exclusions> 35 <exclusion> 36 <groupId>org.junit.vintage</groupId> 37 <artifactId>junit-vintage-engine</artifactId> 38 </exclusion> 39 </exclusions> 40 </dependency> 41 42 <!-- webservice技術,cxf是apache封裝的webservice技術的框架 --> 43 <dependency> 44 <groupId>org.apache.cxf</groupId> 45 <artifactId>cxf-spring-boot-starter-jaxws</artifactId> 46 <version>3.2.5</version> 47 </dependency> 48 <dependency> 49 <groupId>org.springframework.boot</groupId> 50 <artifactId>spring-boot-starter-web-services</artifactId> 51 </dependency> 52 </dependencies> 53 54 <build> 55 <plugins> 56 <plugin> 57 <groupId>org.springframework.boot</groupId> 58 <artifactId>spring-boot-maven-plugin</artifactId> 59 </plugin> 60 </plugins> 61 <resources> 62 <resource> 63 <directory>src/main/resources</directory> 64 <includes> 65 <include>**/*.properties</include> 66 <include>**/*.yml</include> 67 <include>**/*.xml</include> 68 <include>**/*.p12</include> 69 <include>**/*.html</include> 70 <include>**/*.jpg</include> 71 <include>**/*.png</include> 72 </includes> 73 </resource> 74 </resources> 75 </build> 76 77 </project>
創建一個實體類,用戶信息的返回和封裝,如下所示:
1 package com.demo.po; 2 3 import java.io.Serializable; 4 5 public class UserInfo implements Serializable { 6 7 /** 8 * 9 */ 10 private static final long serialVersionUID = 1L; 11 12 private Integer userId;// 用戶編號 13 14 private String userAccount;// 用戶賬號 15 16 private String userPw;// 用戶密碼 17 18 private String userName;// 用戶姓名 19 20 private Integer userAge;// 用戶年齡 21 22 private String userSex;// 用戶性別 23 24 public Integer getUserId() { 25 return userId; 26 } 27 28 public void setUserId(Integer userId) { 29 this.userId = userId; 30 } 31 32 public String getUserAccount() { 33 return userAccount; 34 } 35 36 public void setUserAccount(String userAccount) { 37 this.userAccount = userAccount; 38 } 39 40 public String getUserPw() { 41 return userPw; 42 } 43 44 public void setUserPw(String userPw) { 45 this.userPw = userPw; 46 } 47 48 public String getUserName() { 49 return userName; 50 } 51 52 public void setUserName(String userName) { 53 this.userName = userName; 54 } 55 56 public Integer getUserAge() { 57 return userAge; 58 } 59 60 public void setUserAge(Integer userAge) { 61 this.userAge = userAge; 62 } 63 64 public String getUserSex() { 65 return userSex; 66 } 67 68 public void setUserSex(String userSex) { 69 this.userSex = userSex; 70 } 71 72 @Override 73 public String toString() { 74 return "UserInfo [userId=" + userId + ", userAccount=" + userAccount + ", userPw=" + userPw + ", userName=" 75 + userName + ", userAge=" + userAge + ", userSex=" + userSex + "]"; 76 } 77 78 79 }
定義Webservice接口,接口需要注解@WebService注解和@WebMethod注解的,如下所示:
1 package com.demo.service; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebParam; 5 import javax.jws.WebService; 6 7 /** 8 * 9 * @author 10 * 11 */ 12 @WebService // 定義接口為一個webservice服務,定義服務,在類上邊,作用在具體類上 13 public interface UserInfoWebService { 14 15 /** 16 * 定義方法為一個webservice方法 17 * 18 * @WebParam-定義參數,在方法參數前邊,用於定義wsdl中的參數映射,定制單個參數到web service消息部分和xml元素的映射關系 19 * 20 * @param userId 21 * @return 22 */ 23 @WebMethod // 定義方法,在公開方法上邊,此注解用在方法上,用於修改對外暴漏的方法,定制返回值到wsdl部分和xml元素的映射關系 24 public String getUserInfo(@WebParam(name = "userId") String userId); 25 26 }
定義接口實現類:targetNamespace 的值最好是包名反寫,endpointInterface 是webservice接口的地址,這里參數配置也可以使用自動生成的,看個人需求的,注意這里我配置之后報錯了(說明:是因為我配置錯誤,報的錯,但是不影響SoapUI工具調用,但是客戶端訪問就報錯了,這里進行說明一下),所以去掉自定義配置了,讓其自動生成了。
注意給這個類添加@Component直接注入到spring中,或者在配置類中注入bean的方式進行注入到容器中,如下所示:
1 package com.demo.service.impl; 2 3 import javax.jws.WebService; 4 5 import com.demo.po.UserInfo; 6 import com.demo.service.UserInfoWebService; 7 8 /** 9 * 10 * @author 11 * 12 */ 13 // @WebService( 14 // targetNamespace = "http://impl.service.demo.com/", 15 // endpointInterface = "com.demo.service.impl.UserInfoWebServiceImpl") 16 @WebService 17 public class UserInfoWebServiceImpl implements UserInfoWebService { 18 19 @Override 20 public UserInfo getUserInfo(Integer userId) { 21 System.out.println("---------------------------------userId--------------------------- : " + userId); 22 UserInfo userInfo = new UserInfo(); 23 userInfo.setUserId(userId); 24 userInfo.setUserAccount("張姍姍"); 25 userInfo.setUserPw("123456"); 26 userInfo.setUserAge(26); 27 userInfo.setUserSex("男"); 28 userInfo.setUserName("張姍姍"); 29 return userInfo; 30 } 31 32 }
定義Web service接口服務的配置類:該類的作用是將改Web service服務以userInfoWebService的名稱發布出去,如下所示:
1 package com.demo.config; 2 3 import javax.xml.ws.Endpoint; 4 5 import org.apache.cxf.Bus; 6 import org.apache.cxf.bus.spring.SpringBus; 7 import org.apache.cxf.jaxws.EndpointImpl; 8 import org.apache.cxf.transport.servlet.CXFServlet; 9 import org.springframework.boot.web.servlet.ServletRegistrationBean; 10 import org.springframework.context.annotation.Bean; 11 import org.springframework.context.annotation.Configuration; 12 13 import com.demo.service.UserInfoWebService; 14 import com.demo.service.impl.UserInfoWebServiceImpl; 15 16 /** 17 * 18 * @author 19 * 20 */ 21 @Configuration 22 public class WebServiceConfig { 23 24 @Bean(name = "cxfServlet") // 注入servlet bean name不能dispatcherServlet ,否則會覆蓋dispatcherServlet 25 public ServletRegistrationBean<CXFServlet> cxfServlet() { 26 return new ServletRegistrationBean<CXFServlet>(new CXFServlet(), "/webservice/*"); 27 } 28 29 @Bean 30 public UserInfoWebService userInfoWebService() { 31 return new UserInfoWebServiceImpl(); 32 } 33 34 @Bean(name = Bus.DEFAULT_BUS_ID) 35 public SpringBus springBus() { 36 return new SpringBus(); 37 } 38 39 @Bean 40 public Endpoint endpoint() { 41 // 參數二,是SEI實現類對象 42 EndpointImpl endpoint = new EndpointImpl(this.springBus(), this.userInfoWebService()); 43 // 發布服務 44 endpoint.publish("/userListService"); 45 return endpoint; 46 } 47 48 }
在瀏覽器輸入http://localhost:8080/webservice/userListService?wsdl,如下所示:
在將Springboot和CXF集成之后,如果沒有在配置類中配置ServletRegistrationBean的話,訪問地址是無法獲取到wsdl的穩定的,解決辦法就是new ServletRegistrationBean<CXFServlet>(new CXFServlet(), "/webservice/*");注入一個bean。
使用SoapUI工具或者自己編寫客戶端去測試服務接口,這里先使用SoapUI工具進行測試,稍后自己編寫客戶端進行調用測試,如下所示:
SoapUI工具安裝參考:https://www.cnblogs.com/Sweettesting/p/11399534.html,我這里使用的還是5.1.2版本,有的使用的是5.3.0版本的,界面略有不通。
SoapUI工具使用教程參考:https://blog.csdn.net/w0002399/article/details/82051404
這里可以選擇使用上面的xml界面或者使用下面的表單界面都可以,看個人需求,效果如下所示:
4、如何進行客戶端訪問呢,簡單的客戶端訪問,動態調用的方式,缺點是只能返回Object對象,如下所示:
1 package com.demo.utils; 2 3 import org.apache.cxf.endpoint.Client; 4 import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; 5 6 public class WebServiceClient { 7 8 public static void main(String[] args) { 9 // 代理工廠 10 JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); 11 // 接口地址,這里如果是不是本公司的,需要將wsdl下載到本地的項目中,然后引用本地的哦 12 Client client = dcf.createClient("http://localhost:8080/webservice/userListService?wsdl"); 13 // 可以在此處配置入攔截器或者出攔截器 14 // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD)); 15 Object[] objects = new Object[0]; 16 try { 17 // invoke("方法名",參數1,參數2,參數3....); 18 // 切記invoke的第一個參數是方法的名稱,第二個參數是一個可變參數 19 objects = client.invoke("getUserInfo", 1); 20 System.out.println("返回數據:" + objects[0]); 21 } catch (java.lang.Exception e) { 22 e.printStackTrace(); 23 } 24 } 25 26 }
此時,如果啟動項目,會報下面的錯誤,解決方法就是右擊項目,Properties,然后找到Java Build Path,使用jdk的環境即可,如果使用jre的環境就會報下面的錯誤:
1 12:22:58.036 [main] DEBUG org.apache.cxf.common.logging.LogUtils - Using org.apache.cxf.common.logging.Slf4jLogger for logging. 2 12:22:58.519 [main] DEBUG org.apache.cxf.endpoint.dynamic.DynamicClientFactory - Creating client from WSDL http://localhost:8080/webservice/userListService?wsdl 3 12:22:58.620 [main] DEBUG org.apache.cxf.resource.DefaultResourceManager - resolving resource <org.apache.cxf.wsdl11.WSDLManagerImpl/bus> type <interface org.apache.cxf.Bus> 4 12:22:58.621 [main] DEBUG org.apache.cxf.resource.DefaultResourceManager - resolving resource <null> type <interface org.apache.cxf.Bus> 5 12:22:59.028 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been (re)configured for plain http. 6 12:22:59.030 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 7 12:22:59.030 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Auth Supplier configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 8 12:22:59.030 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been configured for plain http. 9 12:22:59.032 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - registering incoming observer: org.apache.cxf.transport.TransportURIResolver$1@2c34f934 10 12:22:59.103 [main] DEBUG org.apache.cxf.transport.http.Headers - Accept: */* 11 12:22:59.104 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit'. An affirmative Trust Decision is assumed. 12 12:22:59.390 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been (re)configured for plain http. 13 12:22:59.390 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 14 12:22:59.391 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Auth Supplier configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 15 12:22:59.391 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been configured for plain http. 16 12:22:59.391 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - registering incoming observer: org.apache.cxf.transport.TransportURIResolver$1@3427b02d 17 12:22:59.392 [main] DEBUG org.apache.cxf.transport.http.Headers - Accept: */* 18 12:22:59.392 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit'. An affirmative Trust Decision is assumed. 19 Exception in thread "main" java.lang.IllegalStateException: Unable to create schema compiler 20 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompilerWithDefaultAllocator(JAXBUtils.java:744) 21 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createSchemaCompiler(DynamicClientFactory.java:445) 22 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:325) 23 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:243) 24 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:236) 25 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:191) 26 at com.demo.utils.WebServiceClient.main(WebServiceClient.java:12) 27 Caused by: javax.xml.bind.JAXBException 28 - with linked exception: 29 [java.lang.ClassNotFoundException: com/sun/tools/internal/xjc/api/XJC] 30 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompiler(JAXBUtils.java:729) 31 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompilerWithDefaultAllocator(JAXBUtils.java:736) 32 ... 6 more 33 Caused by: java.lang.ClassNotFoundException: com/sun/tools/internal/xjc/api/XJC 34 at java.lang.Class.forName0(Native Method) 35 at java.lang.Class.forName(Unknown Source) 36 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompiler(JAXBUtils.java:722) 37 ... 7 more
修改完jdk的環境之后,如果啟動客戶端訪問,就會報下面的錯誤,這里就需要注意了,
1 12:39:55.490 [main] DEBUG org.apache.cxf.common.logging.LogUtils - Using org.apache.cxf.common.logging.Slf4jLogger for logging. 2 12:39:55.996 [main] DEBUG org.apache.cxf.endpoint.dynamic.DynamicClientFactory - Creating client from WSDL http://localhost:8080/webservice/userListService?wsdl 3 12:39:56.061 [main] DEBUG org.apache.cxf.resource.DefaultResourceManager - resolving resource <org.apache.cxf.wsdl11.WSDLManagerImpl/bus> type <interface org.apache.cxf.Bus> 4 12:39:56.062 [main] DEBUG org.apache.cxf.resource.DefaultResourceManager - resolving resource <null> type <interface org.apache.cxf.Bus> 5 12:39:56.287 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been (re)configured for plain http. 6 12:39:56.288 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 7 12:39:56.289 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Auth Supplier configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 8 12:39:56.290 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been configured for plain http. 9 12:39:56.295 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - registering incoming observer: org.apache.cxf.transport.TransportURIResolver$1@3ee0fea4 10 12:39:56.333 [main] DEBUG org.apache.cxf.transport.http.Headers - Accept: */* 11 12:39:56.334 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit'. An affirmative Trust Decision is assumed. 12 12:39:56.739 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been (re)configured for plain http. 13 12:39:56.740 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 14 12:39:56.740 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Auth Supplier configured for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' 15 12:39:56.740 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit' has been configured for plain http. 16 12:39:56.740 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - registering incoming observer: org.apache.cxf.transport.TransportURIResolver$1@7714e963 17 12:39:56.740 [main] DEBUG org.apache.cxf.transport.http.Headers - Accept: */* 18 12:39:56.741 [main] DEBUG org.apache.cxf.transport.http.HTTPConduit - No Trust Decider for Conduit '{http://cxf.apache.org}TransportURIResolver.http-conduit'. An affirmative Trust Decision is assumed. 19 12:39:57.403 [main] DEBUG org.apache.cxf.endpoint.dynamic.DynamicClientFactory - Created classes: com.demo.service.GetUserInfo, com.demo.service.GetUserInfoResponse, com.demo.service.ObjectFactory, com.demo.service.UserInfo 20 org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name {http://impl.service.demo.com/}getUserInfo. 21 at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:331) 22 at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:325) 23 at com.demo.utils.WebServiceClient.main(WebServiceClient.java:19)
解決方案:@WebService(targetNamespace = "http://service.demo.com/", endpointInterface = "com.demo.service.impl.UserInfoWebService")。
這個注解里面targetNamespace是一定要寫的,這是指名我們暴露出去的接口在哪,不寫映射不到,就會報No operation was found with the name {http://impl.service.demo.com/}getUserInfo.這個錯誤 ,請注意targetNamespace最后面有一個斜線。endpointInterface="com.demo.service.impl.UserInfoWebService" 這個是告訴接口是那個,不配置也報錯。
1 package com.demo.service.impl; 2 3 import javax.jws.WebService; 4 5 import com.demo.po.UserInfo; 6 import com.demo.service.UserInfoWebService; 7 8 /** 9 * 10 * @author 11 * 12 */ 13 @WebService( 14 targetNamespace = "http://service.demo.com/", 15 endpointInterface = "com.demo.service.UserInfoWebService") 16 // @WebService 17 public class UserInfoWebServiceImpl implements UserInfoWebService { 18 19 @Override 20 public UserInfo getUserInfo(Integer userId) { 21 System.out.println("---------------------------------userId--------------------------- : " + userId); 22 UserInfo userInfo = new UserInfo(); 23 userInfo.setUserId(userId); 24 userInfo.setUserAccount("張姍姍"); 25 userInfo.setUserPw("123456"); 26 userInfo.setUserAge(26); 27 userInfo.setUserSex("男"); 28 userInfo.setUserName("張姍姍"); 29 return userInfo; 30 } 31 32 }
5、下面使用代理類工廠的方式,獲取到自己的對象,進行調用,返回自己需要的內容,如下所示:
1 package com.demo.utils; 2 3 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; 4 5 import com.demo.po.UserInfo; 6 import com.demo.service.UserInfoWebService; 7 8 public class WebServiceClient { 9 10 public static void main(String[] args) { 11 try { 12 // 接口地址 13 String address = "http://localhost:8080/webservice/userListService?wsdl"; 14 // 代理工廠 15 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); 16 // 設置代理地址 17 jaxWsProxyFactoryBean.setAddress(address); 18 // 設置接口類型 19 jaxWsProxyFactoryBean.setServiceClass(UserInfoWebService.class); 20 // 創建一個代理接口實現 21 UserInfoWebService userInfoWebService = (UserInfoWebService) jaxWsProxyFactoryBean.create(); 22 // 數據准備 23 Integer userId = 1; 24 // 調用代理接口的方法調用並返回結果 25 UserInfo userInfo = userInfoWebService.getUserInfo(userId); 26 System.out.println("返回結果: " + userInfo); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 } 31 32 }
返回結果,如下所示: