一、webService接口的编写
参考文档:springboot实现WebService接口_springboot webservice接口-CSDN博客
1、引入依赖:
<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.2.7</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
2、定义公共接口,限制命名空间(可忽略)
package cn.bjca.spi.service;
import javax.jws.WebService;
/**
* @Description 这里主要是想要在暴露方法的时候能够统一,方便管理
*
*/
@WebService(targetNamespace = "http://service.spi.bjca.cn/")
public interface ApiService {
}
此接口为了在暴露时对方法进行统一的管理,也可以不用定义公共的接口,直接定义webservice接口,targetNamespase是命名空间,调用时统一值就行,不写是默认为包名的倒序
3、定义webservice接口
如果定义了公共接口,记得在此集成,在此示例为不继承公共接口的样例
package cn.bjca.spi.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @ClassName ApiService
* @Description
* @Date 2024/6/14 16:48
* @Version 1.0
*/
@WebService(targetNamespace = "http://service.spi.bjca.cn/")
public interface ApiCommonService {
@WebMethod(operationName = "commonApi")
String commonApi(@WebParam(name="param1") String param1,@WebParam(name = "param2") String param2);
}
4、webservice实现类
package cn.bjca.spi.service.impl;
import cn.bjca.spi.service.ApiCommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
/**
* @ClassName ApiServiceImpl
* @Description 测试地址:http://127.0.0.1:8099/ws/ApiCommonService?wsdl
* @Date 2024/6/14 16:52
* @Version 1.0
*/
@Component
@WebService(name = "ApiCommonService",
targetNamespace = "http://service.spi.bjca.cn/",
endpointInterface = "cn.bjca.spi.service.ApiCommonService",
portName = "10000")
@Slf4j
public class ApiCommonServiceImpl implements ApiCommonService {
@Override
public String commonApi(String param1,String param2) {
log.info("调用的入参为:"+param1+","+param2);
return "成功";
}
}
5、发布webservice,即配置webservice的config文件
未实现公共接口,需要一个一个注册webservice接口的
package cn.bjca.spi.config;
import cn.bjca.spi.service.ApiCommonService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.xml.ws.Endpoint;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName WebServicePublishConfig
* @Description
* @Date 2024/6/14 16:57
* @Version 1.0
*/
@Configuration
public class WebServicePublishConfig {
@Bean
public ServletRegistrationBean wsServlet(){
return new ServletRegistrationBean(new CXFServlet(),"/ws/*");
}
@Resource
private ApiCommonService apiCommonService;
@Resource
private List<ApiCommonService> apiServices;
@Resource
@Qualifier(Bus.DEFAULT_BUS_ID)
private SpringBus bus;
@Bean
public Endpoint[] endPoint(){
List<Endpoint> endpointList = new ArrayList<>(apiServices.size());
EndpointImpl endpoint = new EndpointImpl(bus, apiCommonService);
String simpleName = apiCommonService.getClass().getSimpleName();
//如果有Impl结尾的类名,去掉Impl
if (simpleName.endsWith("Impl")) {
simpleName = simpleName.substring(0, simpleName.length() - 4);
}
endpoint.publish("/"+simpleName);
endpointList.add(endpoint);
return endpointList.toArray(new Endpoint[0]);
}
}
实现了公用接口的用下面的这个
package com.zhqc.cloud.oms.webService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.xml.ws.Endpoint;
import java.util.ArrayList;
import java.util.List;
/**
* @Author zdd
*/
@Configuration
public class WebServicePublishConfig {
@Bean
public ServletRegistrationBean wsServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/ws/*");
}
@Resource
private List<ApiService> apiServices;
@Resource
@Qualifier(Bus.DEFAULT_BUS_ID)
private SpringBus bus;
@Bean
public Endpoint[] endpoint() {
List<Endpoint> endpointList = new ArrayList<>(apiServices.size());
for (ApiService apiService : apiServices) {
EndpointImpl endpoint = new EndpointImpl(bus, apiService);
String simpleName = apiService.getClass().getSimpleName();
//如果有Impl结尾的类名,去掉Impl
if (simpleName.endsWith("Impl")) {
simpleName = simpleName.substring(0, simpleName.length() - 4);
}
endpoint.publish("/" + simpleName);
endpointList.add(endpoint);
}
return endpointList.toArray(new Endpoint[0]);
}
}
6、测试访问,在浏览器中打开下面地址:
返回,下面内容即发布成功
二、调用webservice接口
参考文献:意外的元素 (uri:““, local:“arg0“)。所需元素为<;{}arg0正确解决方法_意外的元素 url 所需元素为-CSDN博客
1、postman方法:
选择Body->raw,xml格式,内容如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pm="http://www.xxx.com/">
<soapenv:Header/>
<soapenv:Body>
<pm:getClassinfoBasic>
<arg0>123</arg0>
</pm:getClassinfoBasic>
</soapenv:Body>
</soapenv:Envelope>
其中:
(1) xmlns:pm="http://www.xxx.com/",这个与第一种写法参数一致,还是后端配置的那个targetNamespace,和后端配置的保持一致即可。
(2)<pm:getClassinfoBasic></pm:getClassinfoBasic>,这个还是后端的方法名。
(3)<arg0>123</arg0>,还是方法的入参,表示第一个参数传入参123;如果有多个,就用<arg0>123</arg0><arg1>456</arg1>这样即可,配置了webParam注解,需要改成对应的webParam名字。
2、java调用
java调用有多种方法,这里只写一种(使用AXIS调用WebService),具体其他的可以参考:Java 调用 WebService 服务的 3 种方式_java 调用webservice-CSDN博客
2.1、引入依赖:
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
call.setOperationName(new QName("命名空间地址", "方法名"));
package cn.bjca.spi.web.controller;
import cn.bjca.spi.api.facade.SdkDemoFacade;
import cn.bjca.spi.service.SdkDemoService;
import cn.org.bjca.footstone.common.api.web.ReturnResult;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
@RestController
@Slf4j
public class SdkDemoController{
public static void main(String[] args) {
System.out.println(webServer1());
}
public static String webServer1() {
try {
//请求服务地址
String url="http://127.0.0.1:8099/ws/ApiCommonService?wsdl";
//请求命名空间
String targetNameSpace="http://service.spi.bjca.cn/";
//请求方法
String method="commonApi";
Service service = new Service();
Call call = (org.apache.axis.client.Call)service.createCall();
//设置服务地址,指明远程调用的类
call.setTargetEndpointAddress(url);
//call.setOperationName(new QName("命名空间地址", "方法名"));
call.setOperationName(new QName(targetNameSpace,method));
call.setTimeout(60000); //设置超时时间
call.setUseSOAPAction(true);//开启soap
//call.addParameter("参数名称", (参数类型)XMLType.XSD_STRING, ParameterMode.IN(输入、输出));// 接口的参数
call.addParameter("param1", XMLType.XSD_STRING, ParameterMode.IN);
call.addParameter("param2", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);
String result = (String)call.invoke(new Object[]{"1231231","asdfasfd"}); 给方法传递参数,并且调用方法
System.out.println("调用结果:"+ JSONObject.toJSONString(result));
} catch (Exception e) {
e.printStackTrace();
}
return "调用成功";
}
}
三、其他
1、报错提示:意外的元素 (uri:"http://www.xxx.com/", local:"arg0")。所需元素为<{}arg0或者 意外的元素 (uri:"", local:"param3")。所需元素为<{}param1>,<{}param2>
答:这种多是方法的参数未被找到,多半是命名空间的问题,像上面Java的调用addParameter方法中就未指定方法参数的命名空间,默认就是空,所以在定义的webService方法中的参数也不能指定targetNamespace
2、调用提示:Message part {http://service.spi.bjca.cn/}commonApi2 was not recognized.
答:这种也是方法名用错了或者命名空间不对,检查调用时配置的命名空间是否正确
3、就是当webService方法是需要传递对象的时候,如何传值
package com.zhqc.cloud.oms.webService.sku;
import com.zhqc.cloud.oms.webService.ApiService;
import com.zhqc.cloud.oms.webService.sku.entity.SkuKSFNoticeRequest;
import com.zhqc.framerwork.common.model.vo.ResponseVO;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @author zdd
*/
@WebService(targetNamespace = "http://andot.org/webservice/zhqc/server")
public interface ApiSkuService extends ApiService {
/**
* 创建订单
*
* @param skuKSFNoticeRequest 请求参数
* @return ResponseVO 返回结果
*/
@WebMethod
ResponseVO wmsApi(@WebParam(name = "KSF_Notice", targetNamespace = "http://andot.org/webservice/zhqc/server") SkuKSFNoticeRequest skuKSFNoticeRequest);
}
package com.zhqc.cloud.oms.webService.sku;
import com.alibaba.fastjson.JSONObject;
import com.zhqc.cloud.common.model.base.dto.SkuAddOrUpdateReqDTO;
import com.zhqc.cloud.common.utils.ConvertUtil;
import com.zhqc.cloud.oms.api.base.service.ErpSkuService;
import com.zhqc.cloud.oms.api.order.service.ErpOrderService;
import com.zhqc.cloud.oms.webService.sku.entity.SkuDetail;
import com.zhqc.cloud.oms.webService.sku.entity.SkuKSFNoticeRequest;
import com.zhqc.framerwork.common.model.vo.BusinessResponseVO;
import com.zhqc.framerwork.common.model.vo.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.jws.WebService;
import java.util.List;
/**
* @author zdd
*/
@Component
@WebService(name = "ApiService",
targetNamespace = "http://andot.org/webservice/zhqc/server",
endpointInterface = "com.zhqc.cloud.oms.webService.sku.ApiSkuService",
portName = "10000")
@Slf4j
public class ApiSkuServiceImpl implements ApiSkuService {
@Resource
@Lazy
private ErpSkuService erpSkuService;
@Override
public ResponseVO wmsApi(SkuKSFNoticeRequest skuKSFNoticeRequest) {
try {
log.info("接收到SAP数据-saveOrUpdateOfSku:{}", JSONObject.toJSONString(skuKSFNoticeRequest));
List<SkuDetail> skuDetailList = skuKSFNoticeRequest.getSkuElements().getSkuElement().getSkuDetail();
for (SkuDetail skuDetail : skuDetailList) {
erpSkuService.saveOrUpdate(ConvertUtil.cast(skuDetail, SkuAddOrUpdateReqDTO.class));
}
} catch (Exception e) {
log.error("createSku error", e);
return BusinessResponseVO.buildFailVo(e.getMessage());
}
return ResponseVO.success();
}
}
package com.zhqc.cloud.oms.webService.sku.entity;
import lombok.Data;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author zdd
*/
@Data
@XmlRootElement(name = "KSF_Notice", namespace = "http://andot.org/webservice/zhqc/server")
public class SkuKSFNoticeRequest {
private SkuAPIMessage skuApiMessage;
private SkuElements skuElements;
@XmlElement(name = "API_Message", namespace = "http://andot.org/webservice/zhqc/server")
public SkuAPIMessage getSkuApiMessage() {
return skuApiMessage;
}
@XmlElement(name = "Elements", namespace = "http://andot.org/webservice/zhqc/server")
public SkuElements getSkuElements() {
return skuElements;
}
}
package com.zhqc.cloud.oms.webService.sku.entity;
import lombok.Data;
import javax.xml.bind.annotation.XmlElement;
/**
* @author zdd
*/
@Data
public class SkuAPIMessage {
private String guid;
private String sourceSys;
private String targetSys;
private String singleTargetSys;
private String updateTime;
private String appKey;
private String isTest;
private String isManualSend;
@XmlElement(name = "Guid", namespace = "http://andot.org/webservice/zhqc/server")
public String getGuid() {
return guid;
}
@XmlElement(name = "SourceSys", namespace = "http://andot.org/webservice/zhqc/server")
public String getSourceSys() {
return sourceSys;
}
@XmlElement(name = "TargetSys", namespace = "http://andot.org/webservice/zhqc/server")
public String getTargetSys() {
return targetSys;
}
@XmlElement(name = "SingleTargetSys", namespace = "http://andot.org/webservice/zhqc/server")
public String getSingleTargetSys() {
return singleTargetSys;
}
@XmlElement(name = "UpdateTime", namespace = "http://andot.org/webservice/zhqc/server")
public String getUpdateTime() {
return updateTime;
}
@XmlElement(name = "AppKey", namespace = "http://andot.org/webservice/zhqc/server")
public String getAppKey() {
return appKey;
}
@XmlElement(name = "IsTest", namespace = "http://andot.org/webservice/zhqc/server")
public String getIsTest() {
return isTest;
}
@XmlElement(name = "IsManualSend", namespace = "http://andot.org/webservice/zhqc/server")
public String getIsManualSend() {
return isManualSend;
}
}