SpringBoot调用第三方WebService接口的操作技巧(.Wsdl与.Asmx类型)

SpringBoot调webservice接口,一般都会给你url如:

http://10.189.200.170:9201/wharfWebService/services/WharfService?wsdl

http://10.103.6.158:35555/check_ticket/Ticket_Check.asmx

其中.asmx是.net开发提供的webservice服务。

依赖

引入相关依赖:

<!-- webService-->
 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web-services</artifactId>
  </dependency>

  <!-- CXF webservice -->
  <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
      <version>3.2.1</version>
  </dependency>
  <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>3.2.1</version>
  </dependency>
浏览webService提供的方法,确定入参顺序
  1. 直接在浏览器里面访问url,如下

    5D237F42-1D2C-1E35-E0ED-22FE7BE045E3.png

  2. 用SoapUI工具

    CC6721D4-BC46-7539-89D9-0E3A1905F14A.png

  3. 用些是.asmx格式,也可以直接在浏览器访问。会列出方法列表

    8B742967-FA47-4029-9A96-B3E60A2BD445.png

代码

创建client:

package com.gqzdev.sctads.configuration;

import com.gqzdev.sctads.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author gqzdev
 * @date 2021/08/26 15:53
 **/
@Configuration
@Slf4j
public class JaxWsClientConfig {

    @Bean("JaxWsClient")
    public Client client() {
        // 创建动态客户端
        JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();
		//CommonConstant.PUBLIC_SECURITY_URL为连接的url,如http://10.189.200.170:9201/wharfWebService/services/WharfService?wsdl
        log.info("publicsecurity webService url : {}", CommonConstant.PUBLIC_SECURITY_URL);
        //创建client
        Client client = clientFactory.createClient(CommonConstant.PUBLIC_SECURITY_URL);
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setAllowChunking(false);
        // 连接服务器超时时间 10秒
        policy.setConnectionTimeout(10000);
        // 等待服务器响应超时时间 20秒
        policy.setReceiveTimeout(20000);
        conduit.setClient(policy);
        return client;
    }
}

有了client,便可以直接注入调用invoke。找到自己需要调用的方法:

下面只展示一个方法的调用演示,其他的类似

package com.gqzdev.sctads.service.impl;

import com.gqzdev.sctads.constant.CommonConstant;
import com.gqzdev.sctads.service.PublicSecurityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.endpoint.Client;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.xml.namespace.QName;

/**
 * @author gqzdev
 * @date 2021/08/26 15:24
 **/
@Slf4j
@Component
public class PublicSecurityServiceImpl implements PublicSecurityService {


    @Autowired
    @Qualifier("JaxWsClient")
    private Client client;

    /**
     * 旅客登记
     */
    @Override
//    @Async
    public String chineseAddNew(Object... params) {
//        QName qname = new QName("service.", CommonConstant.CHINESE_ADD);
        try {
            Object[] invoke = client.invoke(CommonConstant.CHINESE_ADD, params);
            if (invoke != null && invoke.length >= 1) {
                String result = (String) invoke[0];
                log.info("userAddNew result: {}", result);
                return result;
            }

        } catch (Exception e) {
//            e.printStackTrace();
            log.error("invoke WS userAddNew method error: {}", e.getMessage());
        }
        return null;
    }    
}
使用post请求访问webservice接口
package com.gqzdev.sctads.service.impl;

import cn.hutool.core.util.XmlUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * 对接票务系统验证
 *
 * @author gqzdev
 * @date 2021/08/25 17:07
 **/
@Component
@Slf4j
public class TicketCheckServiceImpl implements TicketCheckService {

    @Autowired
    @Qualifier("nativeRestTemplate")
    private RestTemplate restTemplate;

    @Override
    public boolean ticketCheck(TicketRequestVO ticketRequestVO) {

        //构造请求参数xml
        Map objMap = JSONObject.toJavaObject(JSONObject.parseObject(JSON.toJSONString(ticketRequestVO)), Map.class);
        String objXml = XmlUtil.mapToXmlStr(objMap);
        String requestXml = objXml.replace("<xml>", "<MQ_MESSAGE>").replace("</xml>", "</MQ_MESSAGE>");
        log.info("ticket request params xml: {}", requestXml);

        /**
         * 调用webservice请求
         */
        HttpHeaders headers = new HttpHeaders();
        //header参数
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //请求参数
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        //接口参数
        map.add("msg", requestXml);
        //构造实体对象
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity<>(map, headers);
        //发送post请求webservice
        String response = restTemplate.postForObject(CommonConstant.TICKET_REQUEST_URL, param, String.class);
        log.info("ticket request response: {}", response);

        /**
         * 解析返回xml,返回是否认证成功
         */
        String responseXml = XmlUtil.unescape(response);
        Map<String, Object> resultMap = XmlUtil.xmlToMap(responseXml);
        TicketResponseVO ticketResponseVO = JsonUtil.map2pojo(resultMap, TicketResponseVO.class);
        //0开闸 ,1不开闸
        if (ticketResponseVO.getMQ_MESSAGE().getMSG_BODY().getCOMMAND() == 0) {
            return true;
        }
        return false;
    }


}
XML相关操作

关于xml解析处理,这边推荐使用hutool里面的XmlUtil

相关资料

https://www.iocoder.cn/Spring-Boot/Web-Services

  1. 概述

    在早期的系统中,通过 Web Services 实现服务,提供跨平台、跨语言的远程调用。例如说,艿艿最近在对接的东软 HIS 项目,就是提供 Web Services 接口,让我们的系统进行调用。

友情提示:非必要情况下,胖友可以不阅读本文,因为已经很少系统需要进行 Web Services 对接。并且,老的系统也慢慢逐步切换到 RESTful 接口 + JSON 数据格式。

因为艿艿对 Web Services 了解的也并不多,所以下面的概念主要采用《维基百科 —— Web Services》的内容。

1.1 Web Services 是什么?

Web Services 可使我们的应用程序成为 Web 应用程序。并且,Web Services 可以通过 Web 进行发布、查找和使用。它的关键描述如下:

Web Services 是应用程序组件

Web Services 使用开放协议进行通信

Web Services 是独立的(self-contained)并可自我描述

Web Services 可通过使用 UDDI 来发现

Web Services 可被其他应用程序使用

XML 是 Web Services 的基础

友情提示:看到这里,胖友是不是更加懵逼了?!艿艿也是酱紫过来的,继续往下,不要慌!只要给我们一个示例,咱就能撬动整个地球!

1.2 Web Services 如何工作?

基础的 Web Services 平台是 XML + HTTP。XML 提供了一种可用于不同的平台和编程语言之间的语言。HTTP 协议是最常用的因特网协议。

1.3 Web Services 三要素?

Web Services 由三种基本元素构成:

SOAP(简易对象访问协议)

WSDL(Web Services 描述语言)

UDDI(通用描述、发现及整合)

1.3.1 SOAP

SOAP 是 Simple Object Access Protocol的缩写,它是一个基于 XML 的协议,让应用程序通过 HTTP 交换信息。有或者简单的说,SOAP 是一种用于访问 Web 服务的协议。

SOAP 指简易对象访问协议

SOAP 是一种通信协议

SOAP 用于应用程序之间的通信

SOAP 是一种用于发送消息的格式

SOAP 被设计用来通过因特网进行通信

SOAP 独立于平台

SOAP 独立于语言

SOAP 基于 XML

SOAP 很简单并可扩展

SOAP 允许您绕过防火墙

SOAP 将作为 W3C 标准来发展

友情提示:我们可以将 SOAP 和我们的 RESTful API + JSON 对等,定义了通信方式和格式。

1.3.2 WSDL

WSDL 是 Web Services Description Language 的缩写,它基于 XML 的用于描述 Web Services,以及如何访问 Web Services 的语言。

WSDL 指网络服务描述语言

WSDL 使用 XML 编写

WSDL 是一种 XML 文档

WSDL 用于描述网络服务

WSDL 也可用于定位网络服务

WSDL 还不是 W3C 标准

友情提示:我们可以将 WSDL 和我们的 RESTful API 接口文档对等,定义了具体的接口信息。

1.3.3 UDDI

UDDI 是 Universal Description, Discovery and Integration 的缩写,它- UDDI 指通用的描述、发现以及整合(Universal Description, Discovery and Integration)。

UDDI 是一种用于存储有关 Web Services 的信息的目录。

UDDI 是一种由 WSDL 描述的网络服务接口目录。

UDDI 经由 SOAP 进行通迅。

UDDI 被构建于 Microsoft .NET 平台之中。是一种目录服务,通过它,企业可注册并搜索 Web Services。

友情提示:我们可以将 UDDI 理解成注册中心,通过它可以获得有哪些服务以及服务的地址。

不过本文后续的内容,我们并不会涉及到 UDDI 哈~开森不?!

  1. Spring Web Services

    示例代码对应仓库:lab-65-spring-ws-demo 。

Spring Web Services 项目,是由 Spring 社区开源,专注于文档驱动的方式,构建 Web Services 服务的框架

Spring Web Services 基于契约优先理念开发 SOAP 服务,可以非常灵活的创建 Web Services 服务,并且提供多种方式处理 XML Payload。

Spring Web Services 是基于 Spring 之上,所以我们可以很方便的使用 Spring 依赖注入等等功能。

Spring Web Services (Spring-WS) is a product of the Spring community focused on creating document-driven Web services.

Spring Web Services aims to facilitate contract-first SOAP service development, allowing for the creation of flexible web services using one of the many ways to manipulate XML payloads.

The product is based on Spring itself, which means you can use the Spring concepts such as dependency injection as an integral part of your Web service.

Spring Web Services 由四个子模块组成,由下图所示:

项目依赖

① spring-ws-core:它是 Spring Web Services 的核心模块,提供 WebServiceMessage 和 SoapMessage 等核心接口,具有强大的消息分发功能的服务端框架,和用于 Web Services 端点的各种支持类。同时,它还提供了用于 Web Service 客户端 的 WebServiceTemplate 操作类。

② spring-xml:提供 Spring Web Services 的 XML 支持类。该模块主要针对 spring-ws-core 本身,而不是 Web 服务开发人员。

③ spring-ws-security:该模块给 spring-ws-core 安全方面的功能。通过这个模块,可以添加身份令牌、签名、加解密 SOAP 消息。另外,它可以集成 Spring Security 框架来实现认证与授权的功能。

④ spring-ws-support:该模块提供其它通信方式的支持,例如说 JMS、Email、XMPP 等等。

哔哔了这么多 Spring Web Services 的介绍,我们来撸个具体示例。

2.1 搭建 Web Services 服务端

创建 lab-65-spring-ws-demo-user-service 项目,基于 Spring Web Services 实现一个提供用户服务。项目结构如下图:

项目结构

2.1.1 创建 XSD 文件

创建 users.xsd 文件,描述 Web Services 消息(请求和响应)的数据结构。如下图所示:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-spring-ws-demo"
           elementFormDefault="qualified">

    <!-- 获得用户请求 -->
    <xs:element name="UserGetRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="id" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <!-- 获得用户响应 -->
    <xs:element name="UserGetResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="id" type="xs:int" />
                <xs:element name="name" type="xs:string"/>
                <xs:element name="gender" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <!-- 创建用户请求 -->
    <xs:element name="UserCreateRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="gender" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <!-- 创建用户响应 -->
    <xs:element name="UserCreateResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="id" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

① 在 <xs:schema /> 标签中,设置了 targetNamespace 属性,声明 Web Services 所在 Namespace。具体的值,可以按照自己的喜好来设置,后续会不断使用到。

② 所有 WebService 的请求必须以 Request 结尾,响应必须以 Response 结尾。

2.1.2 引入依赖

创建 pom.xml 文件,引入 Spring Web Services 相关依赖。

<?xml version="1.0" encoding="UTF-8"?>

lab4-64-spring-ws-demo

cn.iocoder.springboot.labs

1.0-SNAPSHOT

4.0.0

<artifactId>lab-65-spring-ws-demo-user-service</artifactId>

<properties>
    <!-- 依赖相关配置 -->
    <spring.boot.version>2.2.4.RELEASE</spring.boot.version>
    <!-- 插件相关配置 -->
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 实现对 Spring Web Services 的自动化配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>

    <!-- Java WSDL 实现库 -->
    <dependency>
        <groupId>wsdl4j</groupId>
        <artifactId>wsdl4j</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- jaxb2-maven-plugin 插件,用于实现将 XML 生成目标类 -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>2.5.0</version>
            <executions>
                <execution>
                    <id>xjc</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- 源文件地址 -->
                <sources>
                    <source>${project.basedir}/src/main/resources/users.xsd</source>
                </sources>
                <!-- 生成代码目标包 -->
                <packageName>cn.iocoder.springboot.lab65.userservice.model</packageName>
            </configuration>
        </plugin>
    </plugins>
</build>
① 引入 spring-boot-starter-web-services 依赖,从而引入 Spring Web Services 相关依赖,并实现其自动配置。

② 引入 wsdl4j 依赖,Java WSDL 实现库。

③ 引入 jaxb2-maven-plugin 插件,用于实现将「2.1.1 创建 XSD 文件」生成具体的 Web Services 请求和响应的类。

标签,设置 XSD 文件所在目录。 标签,设置生成的 Web Services 请求和响应的类所在 package 包。 然后,我们来使用 jaxb2-maven-plugin 进行下生成。如下图所示:

生成结果

2.1.3 WebServicesConfig

创建 WebServicesConfig 配置类,创建 Spring Web Services 相关 Bean。代码如下:

@Configuration

@EnableWs // 开启 Web Services 服务

public class WebServicesConfig extends WsConfigurerAdapter {

public static final String NAMESPACE_URI = "https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-spring-ws-demo";

@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
	MessageDispatcherServlet servlet = new MessageDispatcherServlet();
	servlet.setApplicationContext(applicationContext);
	servlet.setTransformWsdlLocations(true);
	return new ServletRegistrationBean<>(servlet, "/ws/*");
}

@Bean
public XsdSchema usersSchema() {
    return new SimpleXsdSchema(new ClassPathResource("users.xsd"));
}

@Bean(name = "users")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema usersSchema) {
    DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    wsdl11Definition.setLocationUri("/ws");
    wsdl11Definition.setTargetNamespace(NAMESPACE_URI);
    wsdl11Definition.setSchema(usersSchema);
    wsdl11Definition.setPortTypeName("UsersPort");
    return wsdl11Definition;
}

@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
    // 可自定义附加拦截器
}

}

① 在类上添加 @EnableWs 注解,开启 Spring Web Services 服务。

② #messageDispatcherServlet(…) 方法,用于创建用于消息分发的 MessageDispatcherServlet Bean。它的功能和 SpringMVC DispatcherServlet 是一致的,处理流程如下图所示:

MessageDispatcherServlet 处理流程

③ #defaultWsdl11Definition(…) 方法,基于「2.1.1 创建 XSD 文件」构建一个 WSDL 文件。稍后我们来具体瞅瞅~

另外要注意,#defaultWsdl11Definition(…) 方法上的 @Bean 注解设置的 name 名字,决定了 WSDL 最终访问的地址。例如说,此处就对应 http://127.0.0.1:8080/ws/users.wsdl 地址。

2.1.4 UserEndpoint

创建 UserEndpoint 类,提供用户服务 Web Services 端点。代码如下:

@Endpoint

public class UserEndpoint {

@PayloadRoot(namespace = WebServicesConfig.NAMESPACE_URI, localPart = "UserGetRequest")
@ResponsePayload
public UserGetResponse get(@RequestPayload UserGetRequest request) {
    UserGetResponse response = new UserGetResponse();
    response.setId(request.getId());
    response.setName("没有昵称:" + request.getId());
    response.setGender(request.getId() % 2 + 1);
	return response;
}

@PayloadRoot(namespace = WebServicesConfig.NAMESPACE_URI, localPart = "UserCreateRequest")
@ResponsePayload
public UserCreateResponse create(@RequestPayload UserCreateRequest request) {
    UserCreateResponse response = new UserCreateResponse();
    response.setId((int) (System.currentTimeMillis() / 1000));
    return response;
}

}

① 在类上,添加 @Endpoint 注解,声明 UserEndpoint 是一个 Spring Web Services 的端点。

② 在方法上添加 @PayloadRoot 注解,声明该方法对应指定 namespace 下的指定类型 localPart 的请求。

namespace 属性,为我们在「2.1.2 创建 XSD 文件」中的 targetNamespace 属性。

localPart 属性,设置处理的请求名。

③ 在方法参数上,添加 @RequestPayload 注解,设置其对应请求。

④ 在方法上,添加 @ResponsePayload 注解,设置方法的返回为响应。

2.1.5 UserServiceApplication

创建 UserServiceApplication 类,用户服务启动类。代码如下:

@SpringBootApplication

public class UserServiceApplication {

public static void main(String[] args) {
    // 启动 Spring Boot 应用
    SpringApplication.run(UserServiceApplication.class, args);
}

}

2.1.6 简单测试

① 执行 UserServiceApplication 类,启动成功,打印如下日志:

2020-06-16 08:29:44.463 INFO 70202 — [ main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]

② 使用浏览器访问 http://127.0.0.1:8080/ws/users.wsdl 地址,可以看到 WSDL 的内容。如下图所示:

WSDL 内容

2.1.7 SoapUI 测试

下面,我们来使用 SoapUI 进行具体的测试。

SoapUI 提供一个工具通过 SOAP/HTTP 来检查,调用,实现 Web Services 的功能/负载/符合性测试。

① 使用浏览器打开 https://www.soapui.org/downloads/soapui/ 地址,下载 SoapUI Open Source 免费版。如下图所示:

SoapUI 下载地址

下载完成后,点击进行安装。

② 安装完成,点击 SoapUI 打开,进入 SoapUI 主界面。如下图所示:

SoapUI 主界面

③ 点击上方「SOAP」按钮,在「Initial WSDL」输入框中填入 http://127.0.0.1:8080/ws/users.wsdl 地址。如下图所示:

SoapUI 主界面 —— SOAP

点击 OK 确认,完成 SOAP 的导入。如下图所示:

SoapUI 主界面 —— SOAP 示例

④ 点击 Request 1,弹出测试窗口,用于模拟 Web Services 请求。如下图所示:

SoapUI 主界面 —— Request 1

在 <lab:name /> 和 <lab:gender /> 标签中,填写一下,然后点击执行按钮,模拟一次 Web Services 请求。如下图所示:

SoapUI 主界面 —— Request 1 模拟

2.1.8 Postman 测试

在上述的学习中,胖友应该发现,Web Services 本质上就是 HTTP + XML 的组合。因此,我们可以直接使用 Postman 进行模拟测试。如下图所示:

Postman 模拟

具体的请求内容,是可以从 SOAP 请求内容如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lab="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-spring-ws-demo">
   <soapenv:Header/>
   <soapenv:Body>
      <lab:UserCreateRequest>
         <lab:name>WS源码</lab:name>
         <lab:gender>2</lab:gender>
      </lab:UserCreateRequest>
   </soapenv:Body>
</soapenv:Envelope>

2.2 搭建 Web Services 客户端

创建 lab-65-spring-ws-demo-application 项目,基于 Spring Web Services 实现客户端,进行用户服务的调用。项目结构如下图:

项目结构

2.2.1 引入依赖

创建 pom.xml 文件,引入 Spring Web Services 相关依赖。

<?xml version="1.0" encoding="UTF-8"?>

lab4-64-spring-ws-demo

cn.iocoder.springboot.labs

1.0-SNAPSHOT

4.0.0

<artifactId>lab-65-spring-ws-demo-application</artifactId>

<properties>
    <!-- 依赖相关配置 -->
    <spring.boot.version>2.2.4.RELEASE</spring.boot.version>
    <!-- 插件相关配置 -->
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 实现对 Spring WebService 的自动化配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>

    <!-- Java WSDL 实现库 -->
    <dependency>
        <groupId>wsdl4j</groupId>
        <artifactId>wsdl4j</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- maven-jaxb2-plugin 插件,用于实现将 WSDL 生成目标类 -->
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.14.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- WSDL 源文件地址 -->
                <schemaLanguage>WSDL</schemaLanguage>
                <schemas>
                    <schema>
                        <url>http://127.0.0.1:8080/ws/users.wsdl</url>
                    </schema>
                </schemas>
                <!-- 生成代码目标包 -->
                <generatePackage>cn.iocoder.springboot.lab65.demo.wsdl</generatePackage>
            </configuration>
        </plugin>
    </plugins>
</build>
① 和「2.1 搭建 Webb Services 客户端」一样,需要引入 spring-boot-starter-web-services 和 wsdl4j 依赖。

② 引入 maven-jaxb2-plugin 插件,用于实现将用户服务提供的 WSDL 文件,生成具体的 Web Services 请求和响应的类。

和 标签,设置 XSD 文件所在地址。这里,我们设置为用户服务提供的 http://127.0.0.1:8080/ws/users.wsdl 地址。

标签,设置生成的 Web Services 请求和响应的类所在 package 包。

然后,我们来使用 jaxb2-maven-plugin 进行下生成。如下图所示:

生成结果

2.2.2 配置文件

创建 application.yml 配置文件,设置端口为 9090,避免冲突。

server:

port: 9090

2.2.3 UserClient

创建 UserClient 类,创建用户服务的 Web Services 客户端。代码如下:

public class UserClient extends WebServiceGatewaySupport {

public static final String WEB_SERVICES_URI = "http://127.0.0.1:8080/ws";

public UserGetResponse getUser(Integer id) {
    // 创建请求对象
    UserGetRequest request = new UserGetRequest();
    request.setId(id);
    // 执行请求
    return (UserGetResponse) getWebServiceTemplate().marshalSendAndReceive(request);
}

public UserCreateResponse createUser(String name, Integer gender) {
    // 创建请求对象
    UserCreateRequest request = new UserCreateRequest();
    request.setName(name);
    request.setGender(gender);
    // 执行请求
    return (UserCreateResponse) getWebServiceTemplate().marshalSendAndReceive(request);
}

}

① 继承 WebServiceGatewaySupport 类,可以获得 Spring Web Service 客户端 的 WebServiceTemplate 操作类。

② 在每个方法中,通过调用 WebServiceTemplate 的 #marshalSendAndReceive(final Object requestPayload) 方法,实现 Web Services 调用。

2.2.4 WebServicesConfig

创建 WebServicesConfig 配置类,创建「2.2.3 UserClient」Bean 对象。代码如下:

@Configuration

public class WebServicesConfig {

// 创建 Jaxb2Marshaller Bean,实现 XML 与 Bean 的互相转换
@Bean
public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("cn.iocoder.springboot.lab65.demo.wsdl"); // 用户服务的 WSDL 文件
    return marshaller;
}

// 创建 UserClient Bean
@Bean
public UserClient countryClient(Jaxb2Marshaller marshaller) {
    UserClient client = new UserClient();
    client.setDefaultUri("http://127.0.0.1:8080/ws"); // 用户服务的 Web Services 地址
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    return client;
}

}

2.2.5 DemoController

创建 DemoController 类,提供示例 API。代码如下:

@RestController

@RequestMapping("/demo")

public class DemoController {

@Autowired
private UserClient userClient;

@GetMapping("/get")
public String get(@RequestParam("id") Integer id) {
    // 执行 Web Services 请求
    UserGetResponse response = userClient.getUser(id);
    // 响应
    return response.getName();
}

@GetMapping("/create") // 为了方便测试,实际使用 @PostMapping
public Integer create(@RequestParam("name") String name,
                      @RequestParam("gender") Integer gender) {
    // 执行 Web Services 请求
    UserCreateResponse response = userClient.createUser(name, gender);
    // 响应
    return response.getId();
}

}

代码比较简单,胖友一瞅就明白。

2.2.6 DemoApplication

创建 DemoApplication 类,项目启动类。代码如下:

@SpringBootApplication

public class FeignDemoApplication {

public static void main(String[] args) {
    SpringApplication.run(FeignDemoApplication.class, args);
}

}

2.2.7 简单测试

① 执行 DemoApplication 类,启动示例项目。

② 使用浏览器,访问 http://127.0.0.1:9090/demo/get?id=1 地址,成功执行 Web Services 调用。返回结果如下:

没有昵称:1

③ 使用浏览器,访问 http://127.0.0.1:9090/demo/create?name=yudaoyuanma&gender=1 地址,成功执行 Web Services 调用。返回结果如下:

1592281617

3. Feign SOAP 集成

示例代码对应仓库:lab-65-ws-feign-client 。

在《芋道 Spring Boot 声明式调用 Feign 入门》文章中,我们学习了如何使用 Feign 实现声明式调用。

Feign 是由 Netflix 开源的声明式的 HTTP 客户端,目前已经捐献给 OpenFeign 社区。

Feign 的子项目 Feign SOAP 提供了 Web Services 调用的能力,也就是说可以作为 Web Services 的客户端。

Feign SOAP 代码

下面,我们新建 lab-65-ws-feign-client 示例项目,使用 Feign 作为客户端,调用「2. Spring Web Services」小节的用户服务。最终项目如下图所示:

项目结构

3.1 引入依赖

创建 pom.xml 文件,引入 Feign 相关依赖。

<?xml version="1.0" encoding="UTF-8"?>

lab-65

cn.iocoder.springboot.labs

1.0-SNAPSHOT

4.0.0

<artifactId>lab-65-ws-feign-client</artifactId>

<properties>
    <!-- 依赖相关配置 -->
    <spring.boot.version>2.2.4.RELEASE</spring.boot.version>
    <!-- 插件相关配置 -->
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>


<dependencies>
    <!-- 引入 SpringMVC 相关依赖,并实现对其的自动配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- 引入 Feign SOAP 拓展的依赖 -->
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-soap</artifactId>
        <version>11.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- maven-jaxb2-plugin 插件,用于实现将 WSDL 生成目标类 -->
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.14.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- WSDL 源文件地址 -->
                <schemaLanguage>WSDL</schemaLanguage>
                <schemas>
                    <schema>
                        <url>http://127.0.0.1:8080/ws/users.wsdl</url>
                    </schema>
                </schemas>
                <!-- 生成代码目标包 -->
                <generatePackage>cn.iocoder.springboot.lab65.demo.wsdl</generatePackage>
            </configuration>
        </plugin>
    </plugins>
</build>
① 引入 feign-soap 依赖,提供 Feign 针对 SOAP 的拓展。

② 引入 maven-jaxb2-plugin 依赖,用于实现将 WSDL 生成目标类。

然后,我们来使用 jaxb2-maven-plugin 进行下生成。如下图所示:

生成结果

3.2 UserServiceFeignClient

创建 UserServiceFeignClient 类,创建用户服务的 Web Services 客户端。代码如下:

public interface UserServiceFeignClient {

// 获得用户详情
@RequestLine("POST /")
@Headers("Content-Type: text/xml")
UserGetResponse getUser(UserGetRequest request);

// 创建用户
@RequestLine("POST /")
@Headers("Content-Type: text/xml")
UserCreateResponse createUser(UserCreateRequest request);

}

① 添加 @RequestLine(“POST /”) 注解,设置 POST 请求根路径。

② 添加 @Headers(“Content-Type: text/xml”) 注解,因为 Web Services 的请求数据格式是 XML。

③ 方法的入参和返回,使用 maven-jaxb2-plugin 插件生成的类。

3.3 FeignConfig

创建 FeignConfig 配置类,创建 UserServiceFeignClient 代理对象。代码如下:

@Configuration

public class FeignConfig {

private static final JAXBContextFactory JAXB_FACTORY = new JAXBContextFactory.Builder()
        .withMarshallerJAXBEncoding("UTF-8")
        .build();

@Bean
public UserServiceFeignClient userServiceFeignClient() {
    return Feign.builder()
            .encoder(new SOAPEncoder(JAXB_FACTORY))
            .decoder(new SOAPDecoder(JAXB_FACTORY))
            .target(UserServiceFeignClient.class, "http://127.0.0.1:8080/ws"); // 目标地址
}

}

Feign 客户端的编解码器 SOAPEncoder 和 SOAPDecoder,就是由 Feign SOAP 所提供。

3.4 DemoController

创建 DemoController 类,提供示例 API。代码如下:

@RestController

@RequestMapping("/demo")

public class DemoController {

@Autowired
private UserServiceFeignClient userClient;

@GetMapping("/get")
public String get(@RequestParam("id") Integer id) {
    // 请求
    UserGetRequest request = new UserGetRequest();
    request.setId(id);
    // 执行 Web Services 请求
    UserGetResponse response = userClient.getUser(request);
    // 响应
    return response.getName();
}

@GetMapping("/create") // 为了方便测试,实际使用 @PostMapping
public Integer create(@RequestParam("name") String name,
                      @RequestParam("gender") Integer gender) {
    // 请求
    UserCreateRequest request = new UserCreateRequest();
    request.setName(name);
    request.setGender(gender);
    // 执行 Web Services 请求
    UserCreateResponse response = userClient.createUser(request);
    // 响应
    return response.getId();
}

}

代码比较简单,胖友一瞅就明白。

3.5 配置文件

创建 application.yml 配置文件,设置端口为 9090,避免冲突。

server:

port: 9090

3.6 FeignDemoApplication

创建 FeignDemoApplication 类,项目启动类。代码如下:

@SpringBootApplication

public class FeignDemoApplication {

public static void main(String[] args) {
    SpringApplication.run(FeignDemoApplication.class, args);
}

}

3.7 简单测试

① 执行 DemoApplication 类,启动示例项目。

② 使用浏览器,访问 http://127.0.0.1:9090/demo/get?id=1 地址,成功执行 Web Services 调用。返回结果如下:

没有昵称:1

③ 使用浏览器,访问 http://127.0.0.1:9090/demo/create?name=yudaoyuanma&gender=1 地址,成功执行 Web Services 调用。返回结果如下:

1592354015

4. Apache CXF

示例代码对应仓库:lab-65-cxf-ws-demo 。

除了使用「2. Spring Web Services」实现 Web Services 之外,我们也可以使用 Apache CXF 框架。

Apache CXF 是一个开源的服务框架。通过使用 JAX-WS 和 JAX-RS 等等 API,我们基于 CXF 构建和开发服务。

这些服务可以使用各种协议,如 SOAP、XML/HTTP、RESTful HTTP 或 CORBA,并在各种通信方式(如 HTTP、JMS 或 JBI)上工作。

😈 一看概念就懵逼,我们还是来撸个 CXF 的具体示例。

4.1 搭建 Web Services 服务端

创建 lab-65-spring-ws-demo-user-service 项目,基于 Spring Web Services 实现一个提供用户服务。项目结构如下图:

项目结构

4.1.1 引入依赖

创建 pom.xml 文件,引入 CXF 相关依赖。

<?xml version="1.0" encoding="UTF-8"?>

lab-65-spring-ws-demo

cn.iocoder.springboot.labs

1.0-SNAPSHOT

4.0.0

<artifactId>lab-65-cxf-ws-demo-user-service</artifactId>

<properties>
    <!-- 依赖相关配置 -->
    <spring.boot.version>2.2.4.RELEASE</spring.boot.version>
    <!-- 插件相关配置 -->
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 实现 CXF 对 Web Services 的自动配置 -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        <version>3.3.6</version>
    </dependency>
</dependencies>
添加 cxf-spring-boot-starter-jaxws 依赖,引入 CXF 依赖,并实现对 Web Services 的自动配置。

4.1.2 配置文件

创建 application.yml 配置文件,添加 CXF 配置。

CXF 配置项,对应 CxfProperties 配置类

cxf:

path: /ws/ # CXF CXFServlet 的匹配路径

server:

port: 9090 # 设置服务器端口为 9090

① cxf 配置项,对应 CxfProperties 配置类。

通过 cxf.path 配置项,设置 CXF CXFServlet 匹配路径是 /ws/ 开头。其中,CXFServlet 负责分发 CXF Web Services 的请求,和 SpringMVC DispatcherServlet 的功能是一致的。

② server.port 配置项,设置服务器端口为 9090。

4.1.3 UserService

创建 UserService 接口,定义用户服务接口。代码如下:

@WebService(targetNamespace = CXFConfig.NAMESPACE_URI)

public interface UserService {

UserGetResponse get(UserGetRequest request);

UserCreateResponse create(UserCreateRequest request);

}

UserGetRequest 和 UserGetResponse

UserCreateRequest 和 UserCreateResponse

① 在接口上,添加了 @WebService 注解,声明它是一个 Web Services 接口。

targetNamespace 属性:设置 Namespace 命名空间。这里我们设置为 CXFConfig.NAMESPACE_URI

// CXFConfig.java

public static final String NAMESPACE_URI = “https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-cxf-ws-demo”;

具体 Namespace 命名空间的值,胖友可以根据自己的喜好~

② @WebService 注解是 JAX-WS 规范所定义,而 Apache CXF 实现了对该规范的支持,所以本小节的示例都是使用 JAX-WS 的注解来声明 Web Service 服务的噢。

JAX-WS 全称是 Java API for XML-Based Web Services。

JAX-WS 是一种编程模型,它通过注解的方式,简化 Web Services 的开发。

更多 JAX-WS 注解的说明,可以看看《Web Services 注解总结》文章。

4.1.4 UserServiceImpl

创建 UserServiceImpl 类,实现「4.1.3 UserService」接口,用户服务的具体实现。代码如下:

@Service

@WebService(

serviceName = “userService”, // 服务名称

targetNamespace = CXFConfig.NAMESPACE_URI // WSDL 命名空间

)

public class UserServiceImpl implements UserService {

@Override
public UserGetResponse get(UserGetRequest request) {
    UserGetResponse response = new UserGetResponse();
    response.setId(request.getId());
    response.setName("没有昵称:" + request.getId());
    response.setGender(request.getId() % 2 + 1);
    return response;
}

@Override
public UserCreateResponse create(UserCreateRequest request) {
    UserCreateResponse response = new UserCreateResponse();
    response.setId((int) (System.currentTimeMillis() / 1000));
    return response;
}

}

① 在类上,添加 Spring @Service 注解,注解到 Spring 容器中。

② 在类上,还是要添加 @WebService 注解,声明它是一个 Web Services 实现。

serviceName 属性:Web Services 服务名称。

targetNamespace 属性:设置 Namespace 命名空间,保持和接口上的 @WebService 注解的 targetNamespace 属性一致即可。

艿艿也不早为啥 targetNamespace 属性要接口和实现类都设置一次,反正不设置的话,Web Services 调用会报错。

4.1.5 CXFConfig

创建 CXFConfig 类,进行 CXF 的配置。代码如下:

@Configuration

public class CXFConfig {

public static final String NAMESPACE_URI = "https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-cxf-ws-demo";

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

@Bean
public Endpoint userServiceEndpoint(UserService userService) {
    Endpoint endpoint = Endpoint.create(userService);
    endpoint.publish("/user");//发布地址
    return endpoint;
}

}

① #springBus() 方法,创建一个 SpringBus Bean,用于 Web Services 服务的发布。注意,Bean 的名字一定要是 Bus.DEFAULT_BUS_ID。

② #userServiceEndpoint(…) 方法,创建一个 Endpoint Bean,将 UserService 发布到 /user 路径下。这样,我们后续访问 http://127.0.0.1:9090/ws/user 地址时,就是调用 UserService 用户服务。

4.1.6 UserServiceApplication

创建 UserServiceApplication 类,用户服务启动类。代码如下:

@SpringBootApplication

public class UserServiceApplication {

public static void main(String[] args) {
    // 启动 Spring Boot 应用
    SpringApplication.run(UserServiceApplication.class, args);
}

}

4.1.7 简单测试

① 执行 UserServiceApplication 类,启动成功,打印 Web Services 相关如下日志:

2020-06-17 07:50:10.327 INFO 94728 — [ main] o.a.c.w.s.f.ReflectionServiceFactoryBean : Creating Service {https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-cxf-ws-demo}userService from class cn.iocoder.springboot.lab65.userservice.service.UserService

2020-06-17 07:50:10.768 INFO 94728 — [ main] org.apache.cxf.endpoint.ServerImpl : Setting the server’s publish address to be /user

② 使用浏览器访问 http://127.0.0.1:9090/ws/user?wsdl 地址,可以看到 WSDL 的内容。如下图所示:

WSDL 内容

③ 使用 SoapUI 进行 Web Services 接口测试,示例如下图所示:

SoapUI 测试示例

④ 也可以使用 Postman 进行 Web Services 接口测试,示例如下图所示:

Postman 测试示例

4.2 搭建 Web Services 客户端

创建 lab-65-cxf-ws-demo-application 项目,基于 CXF 实现 Web Services 客户端,进行用户服务的调用。项目结构如下图:

项目结构

4.2.1 WSDL 文件

在 resources 目录,先创建 wsdl 目录,再创建 user.wsdl 文件,内容来自 http://127.0.0.1:9090/ws/user?wsdl 地址提供的用户服务的 WSDL 内容。如下图所示:

user.wsdl 文件

稍后,我们将使用 user.wsdl 自动生成 CXF 的代码,用于调用用户服务。

4.2.2 引入依赖

创建 pom.xml 文件,引入 CXF 相关依赖。

<?xml version="1.0" encoding="UTF-8"?>

lab-65-cxf-ws-demo

cn.iocoder.springboot.labs

1.0-SNAPSHOT

4.0.0

<artifactId>lab-65-cxf-ws-demo-application</artifactId>

<properties>
    <!-- 依赖相关配置 -->
    <spring.boot.version>2.2.4.RELEASE</spring.boot.version>
    <!-- 插件相关配置 -->
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 实现 CXF 对 Web Services 的自动配置 -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        <version>3.3.6</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- cxf-codegen-plugin 插件,用于实现将 WSDL 生成目标类 -->
        <plugin>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-codegen-plugin</artifactId>
            <version>3.2.5</version>
            <executions>
                <execution>
                    <id>generate-sources</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <!-- WSDL 源文件地址 -->
                        <wsdlOptions>
                            <wsdlOption>
                                <wsdl>src/main/resources/wsdl/user.wsdl</wsdl>
                                <wsdlLocation>classpath:wsdl/user.wsdl</wsdlLocation>
                            </wsdlOption>
                        </wsdlOptions>
                        <!-- 生成 Java 代码目录 -->
                        <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
                    </configuration>
                    <goals>
                        <goal>wsdl2java</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
① 添加 cxf-spring-boot-starter-jaxws 依赖,引入 CXF 依赖,并实现对 Web Services 的自动配置。

② 引入 cxf-codegen-plugin 插件,用于实现将用户服务提供的 WSDL 文件,生成具体的 CXF 的代码。

然后,我们来使用 cxf-codegen-plugin 进行下生成。如下图所示:

生成结果

4.2.3 CXFConfig

创建 CXFConfig 类,创建 UserService Bean。代码如下:

@Configuration

public class CXFConfig {

@Bean
public UserService userService() {
    JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
    // 设置 UserService 接口
    jaxWsProxyFactoryBean.setServiceClass(UserService.class);
    // 设置 Web Services 地址
    jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:9090/ws/user");
    // 创建
    return (UserService) jaxWsProxyFactoryBean.create();
}

}

在 #userService() 方法中,通过 JaxWsProxyFactoryBean,基于 UserService 接口,创建调用用户服务的 Web Services 代理。

4.2.4 DemoController

创建 DemoController 类,提供示例 API。代码如下:

@RestController

@RequestMapping("/demo")

public class DemoController {

@Autowired
private UserService userService;

@GetMapping("/get")
public String get(@RequestParam("id") Integer id) {
    UserGetRequest request = new UserGetRequest();
    request.setId(id);
    // 执行 Web Services 请求
    UserGetResponse response = userService.get(request);
    // 响应
    return response.getName();
}

@GetMapping("/create") // 为了方便测试,实际使用 @PostMapping
public Integer create(@RequestParam("name") String name,
                      @RequestParam("gender") Integer gender) {
    // 请求
    UserCreateRequest request = new UserCreateRequest();
    request.setName(name);
    request.setGender(gender);
    // 执行 Web Services 请求
    UserCreateResponse response = userService.create(request);
    // 响应
    return response.getId();
}

}

代码比较简单,胖友一瞅就明白。

4.2.5 DemoApplication

创建 DemoApplication 类,项目启动类。代码如下:

@SpringBootApplication

public class FeignDemoApplication {

public static void main(String[] args) {
    SpringApplication.run(FeignDemoApplication.class, args);
}

}

4.2.6 简单测试

① 执行 DemoApplication 类,启动成功,打印 Web Services 相关如下日志:

创建 UserService 代理的日志

2020-06-17 09:19:38.181 INFO 95812 — [ main] o.a.c.w.s.f.ReflectionServiceFactoryBean : Creating Service {https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-65/lab-65-cxf-ws-demo}UserServiceService from class https.github_com.yunaiv.springboot_labs.tree.master.lab_65.lab_65_cxf_ws_demo.UserService

② 使用浏览器,访问 http://127.0.0.1:8080/demo/get?id=1 地址,成功执行 Web Services 调用。返回结果如下:

没有昵称:1

③ 使用浏览器,访问 http://127.0.0.1:8080/demo/create?name=yudaoyuanma&gender=1 地址,成功执行 Web Services 调用。返回结果如下:

1592281617

收藏 (0)
评论列表
正在载入评论列表...
我是有底线的
为您推荐
    暂时没有数据