jdk17+springboot使用webservice的踩坑实战记录
作者:未兆
这篇文章主要给大家介绍了关于jdk17+springboot使用webservice踩坑的相关资料,网上很多教程是基于jdk8的,所以很多在17上面跑不起来,折腾两天,直接给答案,需要的朋友可以参考下
这几天wms对接lbpm系统,给我的接口是webservice的,老实说,这个技术很早,奈何人家只支持这个。
环境说明:JDK17 springboot2.6.6。网上很多教程是基于jdk8的,所以很多在17上面跑不起来。折腾两天,直接给答案。
因为springboot版本不是3.0,用不了cxf-spring-boot-starter-jaxws 的4版本,会各种稀奇报错,或许是我姿势不对,就没继续折腾了。
如果你是springboot3,请用4版本
动态代理调用的时候需要一个参数一个参数排列传,不是一个对象。
- pom文件需要引入,版本按照这个,测试通过的版本。
<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配置
#这个是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; } }
- 服务端写法
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调用 * 将接口信息注册到接口平台上,soap接口调用接口平台配置实现透传 */ @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; /** * 获取指定异构系统的表单模板集合 * * @param sysId 异构系统标识,此为异构系统配置中的唯一标识(sysId) * @param language 语种,默认为空,即中文 * @return 表单模板集合。返回值示例;[{"systemId":"系统标识","modelId":"模块标识","modelName": * "模块名称" * ,"templateFormId":"表单模板标识","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); } /** * 获取指定异构系统的指定模块,指定表单模板的字段元数据描述集合 * * @param sysId 异构系统标识,此为异构系统配置中的唯一标识(sysId) * @param modelId 异构系统模块ID * @param templateFormId 异构系统表单模板ID * @param language 语种,默认为空,即中文 * @return 字段元数据描述集合。返回值示例:[{"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); } /** * 查询流程事件调用的业务函数信息 * * @param sysId 异构系统标识,此为异构系统配置中的唯一标识(sysId) * @param modelId 异构系统模块ID * @param templateFormId 异构系统表单模板ID * @param language 语种,默认为空,即中文 * @return 业务函数信息集。返回值示例:[{{"functionId":"函数标识","functionName":"函数标识","functionDes" * :"函数描述"}] */ @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); } /** * 获取异构系统指定表单实例的指定字段的值 * * @param sysId 异构系统标识,此为异构系统配置中的唯一标识(fdCode) * @param modelId 异构系统模块ID * @param templateFormId 异构系统表单模板ID * @param formInstanceId 异构系统表单实例ID * @param fieldIds 表单字段ID集,多值以逗号分隔 * @param language 语种,默认为空,即中文 * @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); } /** * 执行指定函数的业务逻辑 * * @param formId 异构系统表单信息。格式:{"sysId":"异构系统标识","modelId":"模块ID", * "templateFormId":"表单模板ID", "formInstanceId":"表单实例ID"} * @param functionId 函数ID * @param processData 流程运行时信息。格式暂定。 * @param language 语种,默认为空,即中文 * @return 是否执行成功。返回值示例:"T" 或 "F:错误信息" */ @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); } }
- 客户端写法,用动态代理的方式,不然类太多了
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() { // 创建动态客户端 JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance(); //根据WebServices接口地址创建client Client client = clientFactory.createClient(wsdlUrl); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); policy.setAllowChunking(false); // 连接服务器超时时间 10秒 policy.setConnectionTimeout(10000); // 等待服务器响应超时时间 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; /** * 调用bpm 客户端 */ @Service public class WebClientImpl { private final static Logger log = LoggerFactory.getLogger(WsClientConfig.class); //注入 @Autowired(required = false) @Qualifier("LbpmWsClient") private Client client; /** * 统一处理方法 */ public String handler(String method, Object... obj) { try { //invoke(接口中的方法名称,方法的参数) 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调用异常:" + e.getMessage()); } return null; } /** * 处理响应报文 */ public String handlerBody(Object[] objects) { return JsonUtil.toJSONString(objects); } /** * test */ public String test(String qq) { return handler("qqCheckOnline", qq); } /** * 创建 */ 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() ); } /** * 当前节点的信息 */ public String getCurrentNodesInfo(GetCurrentNodesInfo getCurrentNodesInfo) { return handler("GetCurrentNodesInfo", getCurrentNodesInfo.getFormId(), getCurrentNodesInfo.getProcessId(), getCurrentNodesInfo.getLanguage() ); } /** * 当前用户操作集 */ public String getOperationList(GetOperationList getOperationList) { return handler("GetOperationList", getOperationList.getFormId(), getOperationList.getProcessId(), getOperationList.getActionUid(), getOperationList.getLanguage() ); } /** * 当前处理人列表 */ public String getApproverList(GetApproverList getApproverList) { return handler("GetApproverList", getApproverList.getFormId(), getApproverList.getProcessId(), getApproverList.getLanguage() ); } }
错误提示:
Caused by: java.lang.ClassNotFoundException: com/sun/tools/internal/xjc/api/XJC
这个需要引入jaxb-xjc。如果这个版本不行,多试验几个,jdk8以后,就需要这个,jdk17我用这个好了,不行多试验几个版本!!!
<dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>2.3.8</version> </dependency>
总结
到此这篇关于jdk17+springboot使用webservice踩坑的文章就介绍到这了,更多相关jdk17 springboot使用webservice内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!