SpringBoot 整合 WebService 加入依赖

这是我参与更文挑战的第 3 天,活动详情查看: 更文挑战

日积月累,水滴石穿 😄

在工作当中经常需要与第三方对接,某些第三方提供的接口是 WebService 类型的,所以需要集成 WebService
由于 SpringBoot提供了 WebServicestarter 组件,所以集成 WebService相当的简单

加入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
xml复制代码<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接口

1
2
3
4
5
6
7
8
9
java复制代码package com.gongj.webservice_server.service;

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

public interface IUserServer {

UserDTO getUser(Long str);
}

创建实体类

1
2
3
4
5
6
7
8
java复制代码@Data
public class UserDTO {

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

创建WebService接口的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
java复制代码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,我这就只在实现类上使用了。这里介绍一下,先来看下它的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码@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 接口全路径

创建 WebService 配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
java复制代码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 文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
xml复制代码<?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>

客户端

加入依赖

1
2
3
4
5
xml复制代码<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.3.4</version>
</dependency>

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码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"}
  • 如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%