jdk17+springboot使用webservice的踩坑實(shí)戰(zhàn)記錄
這幾天wms對(duì)接lbpm系統(tǒng),給我的接口是webservice的,老實(shí)說,這個(gè)技術(shù)很早,奈何人家只支持這個(gè)。
環(huán)境說明:JDK17 springboot2.6.6。網(wǎng)上很多教程是基于jdk8的,所以很多在17上面跑不起來。折騰兩天,直接給答案。
因?yàn)閟pringboot版本不是3.0,用不了cxf-spring-boot-starter-jaxws 的4版本,會(huì)各種稀奇報(bào)錯(cuò),或許是我姿勢(shì)不對(duì),就沒繼續(xù)折騰了。
如果你是springboot3,請(qǐng)用4版本
動(dòng)態(tài)代理調(diào)用的時(shí)候需要一個(gè)參數(shù)一個(gè)參數(shù)排列傳,不是一個(gè)對(duì)象。
- pom文件需要引入,版本按照這個(gè),測(cè)試通過的版本。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>2.3.8</version> </dependency>
- properties配置
#這個(gè)是webservice訪問的路徑 #http://localhost:8899/webservice?wsdl cxf.path=/webservice cxf.servlet.enabled=true cxf.servlet.init.services-list-path=webservice
- 配置文件
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 WebServiceConfig { @Autowired private Bus bus; @Bean public EndpointImpl endpoint() { EndpointImpl endpoint = new EndpointImpl(bus, new WebService()); endpoint.publish("/api"); return endpoint; } }
- 服務(wù)端寫法
package com.zxy.mom.product.wms2.web.bpm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import java.util.HashMap; import java.util.Map; /** * LBPM webservice調(diào)用 * 將接口信息注冊(cè)到接口平臺(tái)上,soap接口調(diào)用接口平臺(tái)配置實(shí)現(xiàn)透?jìng)? */ @Component @javax.jws.WebService(serviceName = "WebService", targetNamespace = "http://product.mom.zxy.com/") public class WebService { private final static Logger logger = LoggerFactory.getLogger(WebService.class); @Resource private ProjectServiceImp projectServiceImp; /** * 獲取指定異構(gòu)系統(tǒng)的表單模板集合 * * @param sysId 異構(gòu)系統(tǒng)標(biāo)識(shí),此為異構(gòu)系統(tǒng)配置中的唯一標(biāo)識(shí)(sysId) * @param language 語種,默認(rèn)為空,即中文 * @return 表單模板集合。返回值示例;[{"systemId":"系統(tǒng)標(biāo)識(shí)","modelId":"模塊標(biāo)識(shí)","modelName": * "模塊名稱" * ,"templateFormId":"表單模板標(biāo)識(shí)","templateFormName":"表單模板名","formUrl" * :"表單Url"}] */ @WebMethod(operationName = "getTemplateFormList") @WebResult(targetNamespace = "http://product.mom.zxy.com/") public String getTemplateFormList(@WebParam(name = "sysId", targetNamespace = "") String sysId, @WebParam(name = "language", targetNamespace = "") String language) { Map<String, String> paramMap = new HashMap<>(2); paramMap.put("sysId", sysId); paramMap.put("language", language); return projectServiceImp.getTemplateFormList(sysId, language); } /** * 獲取指定異構(gòu)系統(tǒng)的指定模塊,指定表單模板的字段元數(shù)據(jù)描述集合 * * @param sysId 異構(gòu)系統(tǒng)標(biāo)識(shí),此為異構(gòu)系統(tǒng)配置中的唯一標(biāo)識(shí)(sysId) * @param modelId 異構(gòu)系統(tǒng)模塊ID * @param templateFormId 異構(gòu)系統(tǒng)表單模板ID * @param language 語種,默認(rèn)為空,即中文 * @return 字段元數(shù)據(jù)描述集合。返回值示例:[{"fieldId":"字段ID","fieldName":"字段名","type":"字段類型" * }] */ @WebMethod(operationName = "getFormFieldList") @WebResult(targetNamespace = "http://product.mom.zxy.com/") public String getFormFieldList(@WebParam(name = "sysId") String sysId, @WebParam(name = "modelId") String modelId, @WebParam(name = "templateFormId") String templateFormId, @WebParam(name = "language") String language) { Map<String, String> paramMap = new HashMap<>(4); paramMap.put("sysId", sysId); paramMap.put("modelId", modelId); paramMap.put("templateFormId", templateFormId); paramMap.put("language", language); return projectServiceImp.getFormFieldList(sysId, modelId, templateFormId, language); } /** * 查詢流程事件調(diào)用的業(yè)務(wù)函數(shù)信息 * * @param sysId 異構(gòu)系統(tǒng)標(biāo)識(shí),此為異構(gòu)系統(tǒng)配置中的唯一標(biāo)識(shí)(sysId) * @param modelId 異構(gòu)系統(tǒng)模塊ID * @param templateFormId 異構(gòu)系統(tǒng)表單模板ID * @param language 語種,默認(rèn)為空,即中文 * @return 業(yè)務(wù)函數(shù)信息集。返回值示例:[{{"functionId":"函數(shù)標(biāo)識(shí)","functionName":"函數(shù)標(biāo)識(shí)","functionDes" * :"函數(shù)描述"}] */ @WebMethod(operationName = "getMethodInfo") @WebResult(targetNamespace = "http://product.mom.zxy.com/") public String getMethodInfo(@WebParam(name = "sysId") String sysId, @WebParam(name = "modelId") String modelId, @WebParam(name = "templateFormId") String templateFormId, @WebParam(name = "language") String language) { Map<String, String> paramMap = new HashMap<>(4); paramMap.put("sysId", sysId); paramMap.put("modelId", modelId); paramMap.put("templateFormId", templateFormId); paramMap.put("language", language); return projectServiceImp.getMethodInfo(sysId, modelId, templateFormId, language); } /** * 獲取異構(gòu)系統(tǒng)指定表單實(shí)例的指定字段的值 * * @param sysId 異構(gòu)系統(tǒng)標(biāo)識(shí),此為異構(gòu)系統(tǒng)配置中的唯一標(biāo)識(shí)(fdCode) * @param modelId 異構(gòu)系統(tǒng)模塊ID * @param templateFormId 異構(gòu)系統(tǒng)表單模板ID * @param formInstanceId 異構(gòu)系統(tǒng)表單實(shí)例ID * @param fieldIds 表單字段ID集,多值以逗號(hào)分隔 * @param language 語種,默認(rèn)為空,即中文 * @return 指定字段的值集合。返回值示例:[{"fieldId":"字段ID","fieldValue":"字段值"}] */ @WebMethod(operationName = "getFormFieldValueList") @WebResult(targetNamespace = "http://product.mom.zxy.com/") public String getFormFieldValueList(@WebParam(name = "sysId") String sysId, @WebParam(name = "modelId") String modelId, @WebParam(name = "templateFormId") String templateFormId, @WebParam(name = "formInstanceId") String formInstanceId, @WebParam(name = "fieldIds") String fieldIds, @WebParam(name = "language") String language) { Map<String, String> paramMap = new HashMap<>(6); paramMap.put("sysId", sysId); paramMap.put("modelId", modelId); paramMap.put("templateFormId", templateFormId); paramMap.put("formInstanceId", formInstanceId); paramMap.put("fieldIds", fieldIds); paramMap.put("language", language); return projectServiceImp.getFormFieldValueList(sysId, modelId, templateFormId, formInstanceId, fieldIds, language); } /** * 執(zhí)行指定函數(shù)的業(yè)務(wù)邏輯 * * @param formId 異構(gòu)系統(tǒng)表單信息。格式:{"sysId":"異構(gòu)系統(tǒng)標(biāo)識(shí)","modelId":"模塊ID", * "templateFormId":"表單模板ID", "formInstanceId":"表單實(shí)例ID"} * @param functionId 函數(shù)ID * @param processData 流程運(yùn)行時(shí)信息。格式暫定。 * @param language 語種,默認(rèn)為空,即中文 * @return 是否執(zhí)行成功。返回值示例:"T" 或 "F:錯(cuò)誤信息" */ @WebMethod(operationName = "doMethodProcess") @WebResult(targetNamespace = "http://product.mom.zxy.com/") public String doMethodProcess(@WebParam(name = "formId") String formId, @WebParam(name = "functionId") String functionId, @WebParam(name = "processData") String processData, @WebParam(name = "language") String language) { Map<String, String> paramMap = new HashMap<>(4); paramMap.put("formId", formId); paramMap.put("functionId", functionId); paramMap.put("processData", processData); paramMap.put("language", language); return projectServiceImp.doMethodProcess(formId, functionId, processData, language); } }
- 客戶端寫法,用動(dòng)態(tài)代理的方式,不然類太多了
import org.apache.cxf.endpoint.Client; import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WsClientConfig { private final static Logger logger = LoggerFactory.getLogger(WsClientConfig.class); @Value("${wms.bpmUrl:http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl}") private String wsdlUrl; @Bean("LbpmWsClient") public Client client() { // 創(chuàng)建動(dòng)態(tài)客戶端 JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance(); //根據(jù)WebServices接口地址創(chuàng)建client Client client = clientFactory.createClient(wsdlUrl); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); policy.setAllowChunking(false); // 連接服務(wù)器超時(shí)時(shí)間 10秒 policy.setConnectionTimeout(10000); // 等待服務(wù)器響應(yīng)超時(shí)時(shí)間 20秒 policy.setReceiveTimeout(20000); conduit.setClient(policy); return client; } }
import com.zxy.mom.product.wms2.web.bpm.entity.*; import com.zxy.mom.sdk.common.exception.ConditionException; import com.zxy.mom.sdk.common.util.JsonUtil; import org.apache.cxf.endpoint.Client; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; /** * 調(diào)用bpm 客戶端 */ @Service public class WebClientImpl { private final static Logger log = LoggerFactory.getLogger(WsClientConfig.class); //注入 @Autowired(required = false) @Qualifier("LbpmWsClient") private Client client; /** * 統(tǒng)一處理方法 */ public String handler(String method, Object... obj) { try { //invoke(接口中的方法名稱,方法的參數(shù)) Object[] objects = client.invoke(method, obj); if (objects != null && objects.length > 0) { return handlerBody(objects); } } catch (Exception e) { log.error("拋出了異常:{}", e.getMessage()); throw new ConditionException("webservice調(diào)用異常:" + e.getMessage()); } return null; } /** * 處理響應(yīng)報(bào)文 */ public String handlerBody(Object[] objects) { return JsonUtil.toJSONString(objects); } /** * test */ public String test(String qq) { return handler("qqCheckOnline", qq); } /** * 創(chuàng)建 */ public String createProcess(CreateProcess createProcess) { return handler("CreateProcess", createProcess.getFlowTemplateId(), createProcess.getFormId(), createProcess.getCreator(), createProcess.getExParam(), createProcess.getLanguage() ); } /** * 審批 */ public String approveProcess(ApproveProcess approveProcess) { return handler("ApproveProcess", approveProcess.getFormId(), approveProcess.getProcessId(), approveProcess.getHandler(), approveProcess.getFormData(), approveProcess.getProcessParam(), approveProcess.getLanguage() ); } /** * 可審批 */ public String canApprovalProcess(CanApprovalProcess canApprovalProcess) { return handler("CanApprovalProcess", canApprovalProcess.getFormId(), canApprovalProcess.getActionUid(), canApprovalProcess.getLanguage() ); } /** * 當(dāng)前節(jié)點(diǎn)的信息 */ public String getCurrentNodesInfo(GetCurrentNodesInfo getCurrentNodesInfo) { return handler("GetCurrentNodesInfo", getCurrentNodesInfo.getFormId(), getCurrentNodesInfo.getProcessId(), getCurrentNodesInfo.getLanguage() ); } /** * 當(dāng)前用戶操作集 */ public String getOperationList(GetOperationList getOperationList) { return handler("GetOperationList", getOperationList.getFormId(), getOperationList.getProcessId(), getOperationList.getActionUid(), getOperationList.getLanguage() ); } /** * 當(dāng)前處理人列表 */ public String getApproverList(GetApproverList getApproverList) { return handler("GetApproverList", getApproverList.getFormId(), getApproverList.getProcessId(), getApproverList.getLanguage() ); } }
錯(cuò)誤提示:
Caused by: java.lang.ClassNotFoundException: com/sun/tools/internal/xjc/api/XJC
這個(gè)需要引入jaxb-xjc。如果這個(gè)版本不行,多試驗(yàn)幾個(gè),jdk8以后,就需要這個(gè),jdk17我用這個(gè)好了,不行多試驗(yàn)幾個(gè)版本!??!
<dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>2.3.8</version> </dependency>
總結(jié)
到此這篇關(guān)于jdk17+springboot使用webservice踩坑的文章就介紹到這了,更多相關(guān)jdk17 springboot使用webservice內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中的Eureka服務(wù)過期詳細(xì)解析
這篇文章主要介紹了Spring中的Eureka服務(wù)過期詳細(xì)解析,如果有一些服務(wù)過期了,或者宕機(jī)了,就不會(huì)調(diào)用shutdown()方法,也不會(huì)去發(fā)送請(qǐng)求下線服務(wù)實(shí)例,需要的朋友可以參考下2023-11-11如果淘寶的七天自動(dòng)確認(rèn)收貨讓你設(shè)計(jì)你用Java怎么實(shí)現(xiàn)
在面試的時(shí)候如果面試官問淘寶的七天自動(dòng)確認(rèn)收貨讓你設(shè)計(jì),你會(huì)怎么具體實(shí)現(xiàn)呢?跟著小編看一下下邊的實(shí)現(xiàn)過程,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值2021-09-09