SpringBoot整合cxf發布webService和客戶端的調用
阿新 • • 發佈:2018-08-16
wire 註解 pac point login isp 3.1 component amp
SpringBoot整合cxf發布webService
1. 看看項目結構圖
2. cxf的pom依賴
1 <dependency> 2 <groupId>org.apache.cxf</groupId> 3 <artifactId>cxf-spring-boot-starter-jaxws</artifactId> 4 <version>3.2.4</version> 5 </dependency>
3. 開始編寫webService服務端
3.1 實體類entity
1 package com.example.demo.entity; 2 3 import java.io.Serializable; 4 /** 5 * @ClassName:User 6 * @Description:測試實體 7 * @author Jerry 8 * @date:2018年4月10日下午3:57:38 9 */ 10 public class User implements Serializable{ 11 12 private static final long serialVersionUID = -3628469724795296287L;13 14 private String userId; 15 private String userName; 16 private String email; 17 public String getUserId() { 18 return userId; 19 } 20 public void setUserId(String userId) { 21 this.userId = userId; 22 } 23 public String getUserName() { 24 returnuserName; 25 } 26 public void setUserName(String userName) { 27 this.userName = userName; 28 } 29 public String getEmail() { 30 return email; 31 } 32 public void setEmail(String email) { 33 this.email = email; 34 } 35 @Override 36 public String toString() { 37 return "User [userId=" + userId + ", userName=" + userName + ", email=" + email + "]"; 38 } 39 40 }
3.2 服務接口
package com.example.demo.service; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import com.example.demo.entity.User; /** * @ClassName:UserService * @Description:測試服務接口類 * include:兩個測試方法 * @author Jerry * @date:2018年4月10日下午3:58:10 */ //@WebService(targetNamespace="http://service.demo.example.com")如果不添加的話,動態調用invoke的時候,會報找不到接口內的方法,具體原因未知. @WebService(targetNamespace="http://service.demo.example.com") public interface UserService { @WebMethod//標註該方法為webservice暴露的方法,用於向外公布,它修飾的方法是webservice方法,去掉也沒影響的,類似一個註釋信息。 public User getUser(@WebParam(name = "userId") String userId); @WebMethod @WebResult(name="String",targetNamespace="") public String getUserName(@WebParam(name = "userId") String userId); }
3.3 服務接口的實現類
package com.example.demo.service.impl; import java.util.HashMap; import java.util.Map; import java.util.UUID; import javax.jws.WebService; import org.springframework.stereotype.Component; import com.example.demo.entity.User; import com.example.demo.service.UserService; /** * @ClassName:UserServiceImpl * @Description:測試服務接口實現類 * @author Jerry * @date:2018年4月10日下午3:58:58 */ @WebService(serviceName="UserService",//對外發布的服務名 targetNamespace="http://service.demo.example.com",//指定你想要的名稱空間,通常使用使用包名反轉 endpointInterface="com.example.demo.service.UserService")//服務接口全路徑, 指定做SEI(Service EndPoint Interface)服務端點接口 @Component public class UserServiceImpl implements UserService{ private Map<String, User> userMap = new HashMap<String, User>(); public UserServiceImpl() { System.out.println("向實體類插入數據"); User user = new User(); user.setUserId(UUID.randomUUID().toString().replace("-", "")); user.setUserName("test1"); user.setEmail("[email protected]"); userMap.put(user.getUserId(), user); user = new User(); user.setUserId(UUID.randomUUID().toString().replace("-", "")); user.setUserName("test2"); user.setEmail("[email protected]"); userMap.put(user.getUserId(), user); user = new User(); user.setUserId(UUID.randomUUID().toString().replace("-", "")); user.setUserName("test3"); user.setEmail("[email protected]"); userMap.put(user.getUserId(), user); } @Override public String getUserName(String userId) { return "userId為:" + userId; } @Override public User getUser(String userId) { System.out.println("userMap是:"+userMap); return userMap.get(userId); } }
3.4 發布webService的配置
package com.example.demo.config; import javax.xml.ws.Endpoint; import org.apache.cxf.Bus; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.transport.servlet.CXFServlet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.example.demo.service.UserService; /** * @ClassName:CxfConfig * @Description:cxf發布webservice配置 * @author Jerry * @date:2018年4月10日下午4:12:24 */ @Configuration public class CxfConfig { @Autowired private Bus bus; @Autowired UserService userService; /** * 此方法作用是改變項目中服務名的前綴名,此處127.0.0.1或者localhost不能訪問時,請使用ipconfig查看本機ip來訪問 * 此方法被註釋後:wsdl訪問地址為http://127.0.0.1:8080/services/user?wsdl * 去掉註釋後:wsdl訪問地址為:http://127.0.0.1:8080/soap/user?wsdl * @return */ @SuppressWarnings("all") @Bean public ServletRegistrationBean dispatcherServlet() { return new ServletRegistrationBean(new CXFServlet(), "/soap/*"); } /** JAX-WS * 站點服務 * **/ @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(bus, userService); endpoint.publish("/user"); return endpoint; } }
4. 項目啟動後的wsdl信息
由於圖省事,我將項目的服務端口改為了80,這樣就省去了IP後面寫端口號的麻煩。
5. 兩種調用方式
package com.example.demo.client; import org.apache.cxf.endpoint.Client; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; import com.example.demo.service.UserService; /** * @ClassName:CxfClient * @Description:webservice客戶端: * 該類提供兩種不同的方式來調用webservice服務 * 1:代理工廠方式 * 2:動態調用webservice * @author Jerry * @date:2018年4月10日下午4:14:07 */ public class CxfClient { public static void main(String[] args) { CxfClient.main1(); CxfClient.main2(); } /** * 1.代理類工廠的方式,需要拿到對方的接口地址 */ public static void main1() { try { // 接口地址 String address = "http://127.0.0.1/soap/user?wsdl"; // 代理工廠 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); // 設置代理地址 jaxWsProxyFactoryBean.setAddress(address); // 設置接口類型 jaxWsProxyFactoryBean.setServiceClass(UserService.class); // 創建一個代理接口實現 UserService us = (UserService) jaxWsProxyFactoryBean.create(); // 數據準備 String userId = "maple"; // 調用代理接口的方法調用並返回結果 String result = us.getUserName(userId); System.out.println("返回結果:" + result); } catch (Exception e) { e.printStackTrace(); } } /** * 2:動態調用 */ public static void main2() { // 創建動態客戶端 JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient("http://127.0.0.1/soap/user?wsdl"); // 需要密碼的情況需要加上用戶名和密碼 // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD)); Object[] objects = new Object[0]; try { // invoke("方法名",參數1,參數2,參數3....); objects = client.invoke("getUserName", "maple"); System.out.println("返回數據:" + objects[0]); } catch (java.lang.Exception e) { e.printStackTrace(); } } }
6. 註意點.
誠如之前所說,如果接口的註解上不加targetNamespace的話,動態調用的時候,會報如下的錯誤。
SpringBoot整合cxf發布webService和客戶端的調用