SpringBoot 整合 WebService

Posted king哥Java架构

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot 整合 WebService相关的知识,希望对你有一定的参考价值。

日积月累,水滴石穿 😄

在工作当中经常需要与第三方对接,某些第三方提供的接口是 WebService 类型的,所以需要集成 WebService 由于 SpringBoot提供了 WebServicestarter 组件,所以集成 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 "";
} 
  • name:对应 wsdl:portType 标签,默认值为 Java 类或接口的名称
  • targetNamespace:命名空间,一般写为接口的包名倒序,默认值也是接口的包名倒序。对应 wsdl:definitions:targetNamespace 标签,
  • serviceName:WebService的服务名称,对应wsdl:service,默认值为WebService接口实现类的名称+ “Service”,示例:UserServerImplService
  • portName:对应 wsdl:port标签,默认值为:WebService接口实现类的名称 + “Port”,示例:UserServerImplPort
  • wsdlLocation:指定用于定义 WebService 的 WSDL 文档的地址
  • endpointInterface:WebService 接口全路径

如果你觉得自己学习效率低,缺乏正确的指导,可以加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧!
[Java架构群]
群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的JAVA交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

创建 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"} 

最后

以下是Java面试1—到5年以上开发必问到的面试问点,也都是一线互联网公司Java面试必备技能,下面是参照阿里年薪50W所需具备的技能图,大家可以参考下!
在这里插入图片描述

同时针对这12个技能,我在这整理了一份Java架构进阶面试专题PDF文档(含450题解析,包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发,设计模式,MySQL等知识点解析,内容丰富,图文结合!)

蚂蚁金服Java研发岗三面:MySQL+秒杀+Redis+JVM等(终获offer)
这份专题文档是免费分享的,有需要的朋友可以看向下面来获取!!

需要完整版文档的小伙伴,可以一键三连,下方获取免费领取方式!
在这里插入图片描述

以上是关于SpringBoot 整合 WebService的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 整合 WebService

基于Springboot整合RestTemplate调用Webservice接口

SpringBoot 框架整合webservice

SpringBoot整合cxf发布webService和客户端的调用

springboot 整合 cxf 发布webservice与调用

spring boot整合cxf发布和调用webservice