对于习惯了写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方式调用还有其他方式,更多的参考网上的例子。