webservice 實例 創建與調用
序
對接SAP系統,指定要用webservice 做對接。不然打死也不用webservice,webService也不怎麼流行了,有更好的選擇。
就java webservice而言,框架就有不下十種。網上的教程更是五花八門,零零碎碎,並且很多誤導。 本博將記錄下項目裏用的webservice,以及調用全過程,不誤導。
webservice 選型
試用了幾種,最終選型CXF,這裏不做橫向對比了。用它的原因很簡單
1: CXF順利跑起來了,很順。
2: 跟spring boot 配合得比較好,無需要啓用新的端口(放在restful api 項目,並共用一端口)。
配置
Gradle 配置,maven自行轉換。
compile("org.apache.cxf:cxf-spring-boot-starter-jaxws:3.2.8")
引進來之後下載了一大堆東西,如下
PS: 版本真心是難搞,需要耐心的去試配置,我的jdk是 1.8.0_144
,Spring boot 版本爲 2.0.4.RELEASE
。
代碼
webservice 接口層
package com.ly.mp.swcas.main.webService;
import com.ly.mp.common.entities.RestResult;
import com.ly.mp.swcas.main.wrap.*;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import java.util.List;
@WebService(name = "SwcasService"// 暴露服務名稱
)
public interface SwcasService {
@WebMethod
@WebResult(name = "String", targetNamespace = "")
public String sayHello(@WebParam(name = "userName") String name);
@WebMethod
@WebResult(name = "WsResult", targetNamespace = "")
public WsResult sayHello2(@WebParam(name = "userName") String name);
}
關鍵 1: 註解服務名稱,這個服務名稱將會是webservice 地址的一部分。如 http://localhost:10034/services/SwcasService
?wsdl
@WebService(name = "SwcasService"// 暴露服務名稱
關鍵 2: webservice 方法註解,包括方法以及結果返回註解。
@WebMethod
@WebResult(name = "WsResult", targetNamespace = "")
接口實現
package com.ly.mp.swcas.main.webService;
import javax.jws.WebService;
import com.ly.mp.common.entities.RestResult;
import com.ly.mp.component.entities.UserEntity;
import com.ly.mp.swcas.main.entities.*;
import com.ly.mp.swcas.main.ibiz.*;
import com.ly.mp.swcas.main.wrap.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
@WebService(serviceName = "SwcasService")
@Component
public class SwcasServiceImp implements SwcasService {
@Autowired
private ICarConfigBiz carConfigBiz;
@Autowired
private IDealerBiz dealerBiz;
@Autowired
private IVehicleDespatchBiz vehicleDespatchBiz;
@Autowired
private ISupplierBiz supplierBiz;
@Autowired
private IPartBiz partBiz;
@Override
public String sayHello(String name) {
return "Hello ," + name;
}
@Override
public WsResult sayHello2(String name) {
WsResult rs= new WsResult(1,"成功");
rs.setMsg("測試成功");
rs.setResult(1);
WsResultItem resultItem =new WsResultItem("abc",1,"成功");
rs.getData().add(resultItem);
return rs;
}
關鍵1: 類需要加上組件註解,
@Component
實體
WsResult
package com.ly.mp.swcas.main.webService;
import java.util.ArrayList;
import java.util.List;
public class WsResult {
private int result;
private String msg ;
private List<WsResultItem> data ;
{
data =new ArrayList<>();
}
public WsResult(int result, String msg) {
this.result = result;
this.msg = msg;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public List<WsResultItem> getData() {
return data;
}
public void setData(List<WsResultItem> data) {
this.data = data;
}
}
WsResultItem
package com.ly.mp.swcas.main.webService;
public class WsResultItem {
private String Key;
private int Result;
private String Msg;
public WsResultItem(String key, int result, String msg) {
Key = key;
Result = result;
Msg = msg;
}
public String getKey() {
return Key;
}
public void setKey(String key) {
Key = key;
}
public int getResult() {
return Result;
}
public void setResult(int result) {
Result = result;
}
public String getMsg() {
return Msg;
}
public void setMsg(String msg) {
Msg = msg;
}
}
PS: 與SAP對接主要是同步業務數據,一次同步可能是多條,每第業務數據都帶有唯一的key,我們這邊返回值 需要返回對應key以及處理狀態。
webservice 掛靠配置
package com.ly.mp.swcas.main.config;
import javax.xml.ws.Endpoint;
import com.ly.mp.swcas.main.webService.SwcasService;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CxfConfig {
@Autowired
private Bus bus;
@Autowired
SwcasService swcasService;
/** JAX-WS **/
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, swcasService);
endpoint.publish("/SwcasService");
System.out.println("---------------服務發佈------------------");
return endpoint;
}
}
啓動服務測試
1:輸出日誌裏帶有服務發佈的字眼。
2:服務啓動成功信息
服務測試:
測試地址
根據服務啓動的信息可以知道,我們端口號是10034。
本地webservice 的地址是 :http://localhost:10034/services/SwcasService
webservice 文檔:http://localhost:10034/services/SwcasService?wsdl
如下圖所示:
PS:前面的代碼我做了脫敏,這個截圖實現上把未脫敏的方法都顯示出來了,不要見怪。。
客戶端生成
因爲考慮到服務的複雜性,測試起來相當麻煩。建議使用生成客戶端代碼。
我使用的是 idea 工具。
環境配置
CXF官方下載地址:http://cxf.apache.org/download.html,上面有各種版本。看發佈說明下載。
PS :我試過用最新的版本,無法使用。建議使用3.2.13版本
https://www.apache.org/dyn/closer.lua/cxf/3.2.13/apache-cxf-3.2.13.zip
代碼生成
第一步:
(idea 2020開發工具) tools/WebServices/Generate Java Code From Wsdl。如下圖一
idea 2018 工發工具) 項目文件右擊,彈出菜單。如下圖二
第二步
服務平臺選擇CXF,配置好之後點擊【OK】按鈕。
第三步生成效果如下圖所示。
第四步:找到測試入口文件,如下所示。運行。
第五步:遇到問題,生成的代碼文件編碼不對。
第六步:代碼文檔轉格式
PS:文件可能比較多,一個一個點吧,我的接口比較多,點了20次左右。。
第七步:重複第五步運行,看到輸出結果了,大功告成,如果對你有幫助就點個贊吧
.