SpringBoot интегрирует WebService

задняя часть
SpringBoot интегрирует WebService

Это первый раз, когда я участвую в Gengwen Challenge.3День, подробности о событии уточняйте:Обновить вызов

Со временем капли воды и камни изнашиваются 😄

Во время работы часто необходимо взаимодействовать с третьими сторонами, и интерфейсы, предоставляемые некоторыми третьими сторонами,WebServiceтип, поэтому его нужно интегрироватьWebServiceиз-заSpringBootпри условииWebServiceизstarterкомпоненты, поэтому интегрированныеWebServiceдостаточно просто

добавить зависимости

<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.3.4</version>
</dependency>
<dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
</dependency>

Сервер

Создать интерфейс WebService

package com.gongj.webservice_server.service;

import com.gongj.webservice_server.DTO.UserDTO;
import javax.jws.WebService;

public interface IUserServer {

    UserDTO getUser(Long str);
}

Создать класс сущности

@Data
public class UserDTO {

    private Long id;
    private String name;
    private Integer age;
    private String address;
}

Создайте класс реализации для интерфейса WebService.

package com.gongj.webservice_server.service.impl;

import com.gongj.webservice_server.DTO.UserDTO;
import com.gongj.webservice_server.service.IUserServer;
import org.springframework.stereotype.Service;

import javax.jws.WebService;

@Service
@WebService
public class UserServerImpl implements IUserServer {
    @Override
    public UserDTO getUser(Long id) {
        UserDTO user = new UserDTO();
        user.setId(id);
        user.setAddress("上海市浦东新区");
        user.setAge(25);
        user.setName("gongj");
        return user;
    }
}

Вот заметка@WebService, я использую его только в классе реализации. Давайте представим его здесь, давайте посмотрим на его определение:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface WebService {
    String name() default "";

    String targetNamespace() default "";

    String serviceName() default "";

    String portName() default "";

    String wsdlLocation() default "";

    String endpointInterface() default "";
}
  • имя: соответствующийwsdl:portTypeметка, по умолчанию это имя класса или интерфейса Java
  • targetNamespace: пространство имен, обычно записывается в обратном порядке имени пакета интерфейса, и значение по умолчанию также является обратным порядком имени пакета интерфейса. вести перепискуwsdl:definitions:targetNamespaceЭтикетка,
  • наименование услуги:WebServiceимя службы, соответствующееwsdl:service, значение по умолчаниюWebServiceИмя класса реализации интерфейса + "Сервис", пример:UserServerImplService
  • имя_порта: соответствующееwsdl:portметка, значение по умолчанию:WebServiceИмя класса реализации интерфейса + "Порт", пример:UserServerImplPort
  • wsdlLocation: указано для определенияWebServiceАдрес документа WSDL для
  • интерфейс конечной точки:WebServiceПолный путь к интерфейсу

Создайте класс конфигурации WebService

package com.gongj.webservice_server.config;

import com.gongj.webservice_server.service.IUserServer;
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.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;

@Configuration
public class CxfConfig {

    @Autowired
    private IUserServer userServer;
    /**
     * 注入Servlet 注意beanName不能为dispatcherServlet
     * @return
     */
    @Bean
    public ServletRegistrationBean cxfServlet() {
        return new ServletRegistrationBean(new CXFServlet(),"/webservice/*");
    }

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }


    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), userServer);
        endpoint.publish("/api");
        return endpoint;
    }
}

Запустите службу для доступа:http://localhost:8080/webservice

image.pngНажмите на ссылку, чтобы перейти, мы увидим страницу, это документ описания службы wsdl. Вам также необходимо иметь краткое представление об этом документе.Возможно, сторонняя система напрямую предоставит вам документ wsdl, чтобы вы могли убедиться в этом сами.Примечание: документация wsdl просматривается снизу вверх.

image.png

wsdl-документация

<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:tns="http://impl.service.webservice_server.gongj.com/" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="UserServerImplService" 
targetNamespace="http://impl.service.webservice_server.gongj.com/">


<!-- web service 使用的数据类型 -->
  <wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://impl.service.webservice_server.gongj.com/" elementFormDefault="unqualified" targetNamespace="http://impl.service.webservice_server.gongj.com/" version="1.0">

  <xs:element name="getUser" type="tns:getUser"/>

  <xs:element name="getUserResponse" type="tns:getUserResponse"/>

<!-- getUser 方法的请求参数类型 -->
  <xs:complexType name="getUser">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:long"/>
    </xs:sequence>
  </xs:complexType>

<!-- getUser 方法的响应参数类型 -->
  <xs:complexType name="getUserResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="tns:userDTO"/>
    </xs:sequence>
  </xs:complexType>

<!-- getUser 方法的响应参数的具体类型 -->
  <xs:complexType name="userDTO">
    <xs:sequence>
      <xs:element minOccurs="0" name="address" type="xs:string"/>
      <xs:element minOccurs="0" name="age" type="xs:int"/>
      <xs:element minOccurs="0" name="id" type="xs:long"/>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
  </wsdl:types>
  
  <!-- 
        message:用来定义soap消息结构
        part:引用上面 types 中的约束格式
 -->
  <wsdl:message name="getUser">
    <wsdl:part element="tns:getUser" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getUserResponse">
    <wsdl:part element="tns:getUserResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  
  <!-- 
    portType:用来指定服务器端的接口
    operation:接口中定义的方法
    input:方法getUser的输入
    output:方法getUser的输出
    输入输出引用的是上面message的定义
     -->
  <wsdl:portType name="UserServerImpl">
    <wsdl:operation name="getUser">
      <wsdl:input message="tns:getUser" name="getUser">
    </wsdl:input>
      <wsdl:output message="tns:getUserResponse" name="getUserResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  
  <!-- 
    type属性:引用<portType>的定义
    <soap:binding style="document">:表示传输的一个document (xml)
    <input><output>方法的输入、输出
    <soap:body use="literal" />:表示body传输采用文本即xml格式的文本
-->
  <wsdl:binding name="UserServerImplServiceSoapBinding" type="tns:UserServerImpl">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getUser">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="getUser">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getUserResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  
  <!-- 
    name:用于指定客户端的容器类/工厂类
     binding:引用上面的 binding 标签
     port name:容器通过这个方法获得实现类,自动生成会出现这个类,可以不用管
     address:客户端真正用于请求的地址
     -->
  <wsdl:service name="UserServerImplService">
    <wsdl:port binding="tns:UserServerImplServiceSoapBinding" name="UserServerImplPort">
      <soap:address location="http://localhost:8080/webservice/api"/>
    </wsdl:port>
  </wsdl:service>
  
</wsdl:definitions>

клиент

добавить зависимости

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.3.4</version>
</dependency>

передача

public static void main(String[] args) {
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://localhost:8080/webservice/api?wsdl");
        ObjectMapper mapper = new ObjectMapper();
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            Object[] objects = client.invoke("getUser", 99L);
            System.out.println(mapper.writeValueAsString(objects[0]));
        } catch (java.lang.Exception e) {
            e.printStackTrace();
        }
    }

输出结果:
{"address":"上海市浦东新区","age":25,"id":99,"name":"gongj"}
  • Если у вас есть какие-либо вопросы по этой статье или есть ошибки в этой статье, пожалуйста, оставьте комментарий. Если вы считаете, что эта статья была вам полезна, ставьте лайк и подписывайтесь на нее.