对于习惯了写api接口调用的同学来说,突然写webservice的接口调用还是有那么一丝不自然,感觉有点别扭,整体来说跟其他方法引入一样都是通过pom或gradle把相应jar引入进来,下面我们就来看整体流程:
1.通过pom引入需要用到的jar包:
<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.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
</dependency>
2.jar包引入后,我们就可以进行代码的开发了,如果我们开发的是服务端,需要在对应的service类上或者需要作为服务端的类上添加如下的代码,一般情况下先创建interface:
@WebService(name = "WebServiceToClientService",
targetNamespace = "http://service.test.com")
public interface WebServiceToClientService{
@WebMethod
String testWebService(@WebParam(name = "name") String name);
}
其中注解@WebService表示这个地方是一个webservice接口类,name用于表示唯一的webservice名称,一般与当前类名相同,targetNamespace表示命名空间,一般取为与类名路径倒序的名称,对于要使用的方法需要在对应的方法上加上注解@WebMethod,而参数也使用注解@WebParam来定义。
3.创建一个类来实现接口,如下:
@WebService(name = "WebServiceToClientService",
targetNamespace = "http://service.test.com",
endpointInterface = "com.test.service.WebServiceToClientService")
@Service
public class WebServiceToClientServiceImpl implements WebServiceToClientService
其中在@WebService注解的name和targeNamespace我们可以不用重复定义,而endpointInterface表示接口具体路径,我们定义的路径一般为类的接口路径,剩下的就实现具体业务逻辑即可。
5.配置发布webservice类
在定义完成需要发布的webservice类后,我们需要把这这个webservice类发布出来,因此我们就要配置一个config端点,配置如下:
import com.test.service.WebServiceToClientService;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.xml.ws.Endpoint;
@Configuration
public class CxfConfig {
@Resource
private Bus bus;
@Resource
private WebServiceToClientService webServiceToClientService;
/**
* 发布服务
*
* @return
*/
@Bean
public Endpoint webServiceToClientEndpoint() {
//这里指定的端口不能跟应用的端口冲突, 单独指定,也可以和应用端口一样
String path = "/webServiceToClientService";
EndpointImpl userEndpoint = new EndpointImpl(bus, webServiceToClientService);
userEndpoint.publish(path);
return webServiceToClientService;
}
}
还有一个需要在application.yml里面配置webservice端口的总路径:
cxf:
path: /webservice/service
这样服务端的所有代码都定义完成,剩下的就可以启动服务了。
6.服务启动后我们就可以通过自定的端口(这里应用的端口是9090)访问如下:
http://localhost:9090/webservice/service/webServiceToClientService?wsdl
得到如下定义信息:
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.test.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="WebServiceToClientServiceImplService" targetNamespace="http://service.test.com">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.test.com" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://service.test.com" version="1.0">
<xs:element name="testWebService" type="testWebService"/>
<xs:element name="testWebServiceResponse" type="tns:testWebServiceResponse"/>
<xs:complexType name="testWebService">
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="testWebServiceResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<wsdl:message name="testWebServiceResponse">
<wsdl:part element="tns:testWebServiceResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="testWebService">
<wsdl:part element="tns:testWebService" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:portType name="WebServiceToClientService">
<wsdl:operation name="testWebService">
<wsdl:input message="tns:testWebService" name="testWebService"> </wsdl:input>
<wsdl:output message="tns:testWebServiceResponse" name="testWebServiceResponse"> </wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WebServiceToClientServiceImplServiceSoapBinding" type="tns:WebServiceToClientService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="testWebService">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="testWebService">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="testWebServiceResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WebServiceToClientServiceImplService">
<wsdl:port binding="tns:WebServiceToClientServiceImplServiceSoapBinding" name="WebServiceToClientServicePort">
<soap:address location="http://127.0.0.1:9090/webservice/service/webServiceToClientService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
7.接下来我们就可以定义客户端的代码了,这里直接使用的是axis下的Service类来实现,具体如下:
String endPoint = "http://localhost:9090/webservice/service/webServiceToClientService?wsdl";
org.apache.axis.client.Service service = new org.apache.axis.client.Service();
Call call = service.createCall();
call.setTargetEndpointAddress(endPoint);
// 定义包名和接口方法
call.setOperationName(new QName("http://service.test.com", "testWebservice"));
// 设置参数
call.addParameter("name", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);
String responseInfo = (String) call.invoke(new Object[]{xml});
System.out.println(responseInfo);
除了Service方式调用还有其他方式,更多的参考网上的例子。