1、引入依赖
<!-- CXF webservice --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.2.5</version> </dependency>
关于cxf的版本,要针对不同的spring boot版本选择对应的版本,否则可能会导致容器启动失败:
spring boot的<version>1.5.6.RELEASE</version>版本,可选择cxf的<version>3.1.11</version>版本;
spring boot的<version>2.1.3.RELEASE</version>版本,可选择cxf的<version>3.2.5</version>版本;
2、编写web service接口类:CommonService.java
package com.ybin.webservice.webservice; import com.ybin.webservice.beans.AjaxResult; import com.ybin.webservice.po.MaterialInfo; import com.ybin.webservice.po.SapSecurityInfo; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; /** * @Author: bingy * @Date: 2020.11.9 23:11 * @Version: 1.0 * @Description: **/ @WebService(name = "CommonService", // 暴露服务名称 targetNamespace = "http://fabric.ribo.com/" // 命名空间,一般是接口的包名倒序 ) public interface CommonService { /** * 测试web service * @param name * @return */ @WebMethod @WebResult(name = "String", targetNamespace = "") public String sayHello(@WebParam(name = "userName") String name); /** * 获取sap物料信息 * @param sapSecurityInfo * @param materialInfo * @return */ @WebMethod(action = "putMaterialData") public @WebResult AjaxResult putMaterialData( @WebParam(name = "sapSecurityInfo") SapSecurityInfo sapSecurityInfo, @WebParam(name = "materialInfo") MaterialInfo materialInfo ); }
3、编写web service实现类:CommonServiceImpl.java
package com.ybin.webservice.webservice; import com.alibaba.fastjson.JSONObject; import com.ybin.webservice.beans.AjaxResult; import com.ybin.webservice.po.MaterialInfo; import com.ybin.webservice.po.SapSecurityInfo; import com.ybin.webservice.service.MaterialService; import com.ybin.webservice.util.LogUtils; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.jws.WebService; import javax.xml.ws.BindingType; /** * @Author: bingy * @Date: 2020.11.9 23:27 * @Version: 1.0 * @Description: **/ @WebService(serviceName = "CommonService", // 与接口中指定的name一致 targetNamespace = "http://webservice.ybin.com/", // 与接口中的命名空间一致,一般是接口的包名倒 endpointInterface = "com.ybin.webservice.webservice.CommonService"// 接口地址 ) @BindingType(value = "http://www.w3.org/2003/05/soap/bindings/HTTP/") @Component public class CommonServiceImp implements CommonService { Logger logger = LogUtils.getBussinessLogger(); @Autowired MaterialService materialService; @Override public String sayHello(String name) { return "Hello , " + name; } @Override public AjaxResult putMaterialData(SapSecurityInfo sapSecurityInfo, MaterialInfo materialInfo) { logger.info("sapSecurityInfo->" + JSONObject.toJSONString(sapSecurityInfo)); logger.info("materialInfo->" + JSONObject.toJSONString(materialInfo)); AjaxResult ajaxResult = new AjaxResult(); try { ajaxResult = materialService.saveFromWebService(sapSecurityInfo, materialInfo.getMaterialHeader()); } catch (Exception e) { e.printStackTrace(); String errMsg = e.getMessage() != null ? e.getMessage() : "操作失败"; ajaxResult.setRetcode(AjaxResult.FAILED); ajaxResult.setRetmsg(errMsg); } logger.info("ajaxResult->" + JSONObject.toJSONString(ajaxResult)); return ajaxResult; } }
省略业务相关service层代码...
4、编写cxf配置类:CxfConfig.java
package com.ybin.webservice.config; import com.ybin.webservice.webservice.CommonService; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.Bus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.xml.ws.Endpoint; /** * @Author: bingy * @Date: 2020.11.9 23:45 * @Version: 1.0 * @Description: **/ @Configuration public class CxfConfig { @Autowired private Bus bus; @Autowired CommonService commonService; /** * JAX-WS **/ @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(bus, commonService); endpoint.publish("/CommonService"); return endpoint; } }
5、启动项目,查看wsdl
web service默认发布在 http://localhost:8081/services/ 路径下:
6、用soapUI测试没有问题
7、用ABAP调用web service
*&---------------------------------------------------------------------* *& FORM fm_call_http_client *&---------------------------------------------------------------------* FORM fm_call_http_client. DATA is_zweb_config TYPE zweb_config. SELECT SINGLE * INTO CORRESPONDING FIELDS OF is_zweb_config FROM zweb_config WHERE sysname = 'YBIN_SERVICE' AND ifname = '/services/CommonService?'. IF is_zweb_config IS INITIAL. PERFORM fm_write_log USING '[ERROR]: There is no configurtion about host and port in table [ZWEB_CONFIG]...'. RETURN. ENDIF. soapaction = 'http://' && is_zweb_config-host && ':' && is_zweb_config-port && is_zweb_config-ifname. CONDENSE soapaction NO-GAPS. PERFORM fm_write_log USING soapaction. * 测试代码 * CLEAR soapaction. * soapaction = 'http://10.10.76.193:8081/services/CommonService?'. * CLEAR lv_xml. *lv_xml = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://webservice.ybin.com/">'. * lv_xml = lv_xml && '<soap:Header/>'. * lv_xml = lv_xml && '<soap:Body>'. * lv_xml = lv_xml && '<web:putMaterialData>'. * lv_xml = lv_xml && '<sapSecurityInfo>'. * lv_xml = lv_xml && '<password>EEE</password>'. * lv_xml = lv_xml && '<username>EEE</username>'. * lv_xml = lv_xml && '</sapSecurityInfo>'. * lv_xml = lv_xml && '<materialInfo>'. * lv_xml = lv_xml && '<materialHeader>'. * lv_xml = lv_xml && '<CLABS>1</CLABS>'. * lv_xml = lv_xml && '<EX_SAISJ>2020</EX_SAISJ>'. * lv_xml = lv_xml && '<EX_ZFK></EX_ZFK>'. * lv_xml = lv_xml && '<EX_ZMLCF></EX_ZMLCF>'. * lv_xml = lv_xml && '<EX_ZMLKZ></EX_ZMLKZ>'. * lv_xml = lv_xml && '<j_3AKORDX>color001</j_3AKORDX>'. * lv_xml = lv_xml && '<MAKTX>123</MAKTX>'. * lv_xml = lv_xml && '<MATNR>matnr002</MATNR>'. * lv_xml = lv_xml && '<MEINS>KAN</MEINS>'. * lv_xml = lv_xml && '<VERPR>12.22</VERPR>'. * lv_xml = lv_xml && '</materialHeader>'. * lv_xml = lv_xml && '</materialInfo>'. * lv_xml = lv_xml && '</web:putMaterialData>'. * lv_xml = lv_xml && '</soap:Body>'. *lv_xml = lv_xml && '</soap:Envelope>'. * 创建http_client对象 CALL METHOD cl_http_client=>create_by_url EXPORTING url = soapaction IMPORTING client = http_client. * Display Logon Screen = 1 http_client->propertytype_logon_popup = http_client->co_enabled. * 设置头信息[name,value] CALL METHOD http_client->request->set_header_field EXPORTING name = 'Content-Type' value = 'text/xml;charset="UTF-8"'. CALL METHOD http_client->request->set_header_field EXPORTING name = 'SOAPAction' value = soapaction. CALL METHOD http_client->request->set_header_field EXPORTING name = 'User-Agent' value = 'compatible; MSIE 5.0;'. * 将此实体的HTTP主体设置为char CALL METHOD http_client->request->set_cdata EXPORTING data = lv_xml. * 发送http请求 CALL METHOD http_client->send EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2. * 接收http响应 CALL METHOD http_client->receive EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3. * 返回此实体的HTTP正文作为字符数据 CLEAR lv_log. lv_log = http_client->response->get_cdata( ). CLEAR xmldata. xmldata = http_client->response->get_data( ). * 关闭http连接 CALL METHOD http_client->close. *解析响应返回的数据 CLEAR lt_return[]. CALL FUNCTION 'SMUM_XML_PARSE' EXPORTING xml_input = xmldata TABLES xml_table = lt_retable return = lt_return. PERFORM fm_write_log USING '===== 日志 ======'. DATA iv_log TYPE string. PERFORM fm_write_log USING '[RETLOG]: Returned log:'. WHILE lv_log NE ''. SPLIT lv_log AT '>' INTO iv_log lv_log. iv_log = iv_log && '>'. PERFORM fm_write_log USING iv_log. ENDWHILE. PERFORM fm_write_log USING 'Http Response:'. LOOP AT lt_retable. CLEAR iv_log. iv_log = 'type:' && lt_retable-type && '; name:' && lt_retable-cname && '; value:' && lt_retable-cvalue && ';'. PERFORM fm_write_log USING iv_log. ENDLOOP. ENDFORM.
此处有一点,用ABAP调用web service需要在事务代码:SICF 中配置启用web service。