SpringBoot集成WebService

server/2024/10/21 6:03:22/

Spring集成Webservice(JAX·WS)

初步尝试

  1. 引入依赖

dependencies {// 引入Spring Boot Web Starter,提供基础的Web应用支持,包括Tomcat服务器、Spring MVC等组件 implementation("org.springframework.boot:spring-boot-starter-web")// 引入Spring Boot Web Services Starter,为构建基于Spring的Web服务提供支持,包括对SOAP、RESTful等协议的集成implementation("org.springframework.boot:spring-boot-starter-web-services")// 引入Apache CXF Spring Boot Starter for JAX-WS,用于快速配置和启用CXF作为JAX-WS(SOAP Web服务)实现// 版本号为4.0.4,确保与项目其他组件兼容并获取最新稳定功能及修复implementation("org.apache.cxf:cxf-spring-boot-starter-jaxws:4.0.4")// 引入Spring Boot Test Starter,提供测试所需的各类依赖,如JUnit、Mockito、Spring Test等,用于编写和运行应用程序的单元测试和集成测试testImplementation("org.springframework.boot:spring-boot-starter-test")
}

maven

<!-- pom.xml --><project><!-- ... --><dependencies><!-- 引入Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 引入Spring Boot Web Services Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web-services</artifactId></dependency><!-- 引入Apache CXF Spring Boot Starter for JAX-WS --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-spring-boot-starter-jaxws</artifactId><version>4.0.4</version></dependency><!-- 引入Spring Boot Test Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><!-- ... -->
</project>
  1. 实现服务类的接口,以及实现
java">import jakarta.jws.WebMethod;
import jakarta.jws.WebService;@WebService(name = "MyWebService",targetNamespace = "http://hacoj.com/mywebservice"
)
public interface MyWebService {@WebMethodString sayHello(String name);
}
java">import com.hacoj.springwebservice.service.MyWebService;
import jakarta.jws.WebService;
import org.springframework.stereotype.Service;@Service
@WebService
public class MyWebServiceImpl implements MyWebService {@Overridepublic String sayHello(String name) {System.err.println("sayHello is called..."); // 只是为了更明显的输出,采用errreturn "Hello, " + name + "!";}
}
  1. 配置Spring Boot的Web服务
java">import jakarta.xml.ws.Endpoint;
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;/*** CXF配置类,负责初始化CXF相关组件、发布Webservice服务以及配置CXF Servlet。*/
@Configuration
public class CxfConfig {/*** 自动注入Spring Bus实例,它是CXF的核心组件之一,用于管理和配置CXF运行时环境。*/@Autowiredprivate SpringBus bus;/*** 自动注入实现了MyWebService接口的服务实现类实例,该实例将被发布为Webservice供外部调用。*/@Autowiredprivate MyWebService myWebServiceImpl;/*** 创建并返回Webservice端点(Endpoint)实例,用于发布MyWebService服务。* 将服务实现类与Spring Bus关联,并指定发布地址为"/1"。** @return Webservice端点实例*/@Beanpublic Endpoint endpoint() {EndpointImpl endpoint = new EndpointImpl(bus, myWebServiceImpl);endpoint.publish("/1"); // 发布地址return endpoint;}/*** 创建并返回CXF Servlet的ServletRegistrationBean实例,用于注册CXF Servlet到Spring Boot的Servlet容器中。* 设置CXF Servlet的映射路径为"/services/*",表示所有以"/services/"开头的HTTP请求都将由CXF Servlet处理。** @return CXF Servlet的ServletRegistrationBean实例*/@Beanpublic ServletRegistrationBean wsServlet() {return new ServletRegistrationBean(new CXFServlet(), "/services/*");}
}
  1. 启动Spring Boot应用

测试

访问

http://localhost:8080/services/1?wsdl

结果如下


<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.service.springwebservice.hacoj.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://hacoj.com/mywebservice" name="MyWebServiceImplService" targetNamespace="http://impl.service.springwebservice.hacoj.com/"><wsdl:import location="http://localhost:8080/services/1?wsdl=MyWebService.wsdl" namespace="http://hacoj.com/mywebservice"> </wsdl:import><wsdl:binding name="MyWebServiceImplServiceSoapBinding" type="ns1:MyWebService"><soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="sayHello"><soap:operation soapAction="" style="document"/><wsdl:input name="sayHello"><soap:body use="literal"/></wsdl:input><wsdl:output name="sayHelloResponse"><soap:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="MyWebServiceImplService"><wsdl:port binding="tns:MyWebServiceImplServiceSoapBinding" name="MyWebServiceImplPort"><soap:address location="http://localhost:8080/services/1"/></wsdl:port></wsdl:service>
</wsdl:definitions>

调用

实现一个客户端,调用Webservice服务
客户端的实现代码也比较简单,只需要调用服务端的接口,并处理返回结果即可。

  1. 接口定义类:定义客户端的接口,用于调用服务端的接口。
  2. 客户端启动类:启动客户端,并调用服务端的接口。

依赖

dependencies {// 测试依赖配置testImplementation(platform("org.junit:junit-bom:5.9.1")) // JUnit依赖testImplementation("org.junit.jupiter:junit-jupiter") // JUnit Jupiter测试框架// 主要依赖配置implementation("com.sun.xml.bind:jaxb-impl:4.0.5") // JAXB实现库implementation("javax.xml.bind:jaxb-api:2.3.1") // JAXB API库implementation("jakarta.activation:jakarta.activation-api:2.1.3") // Jakarta Activation API库implementation("jakarta.jws:jakarta.jws-api:3.0.0") // Jakarta JWS API库implementation("jakarta.xml.ws:jakarta.xml.ws-api:4.0.1") // Jakarta XML Web Services API库implementation("jakarta.xml.bind:jakarta.xml.bind-api:4.0.1") // Jakarta XML Binding API库// Apache CXF相关依赖implementation("org.apache.cxf:cxf-rt-transports-http-jetty:4.0.4") // CXF Jetty HTTP传输实现implementation("org.apache.cxf:cxf-rt-frontend-jaxws:4.0.4") // CXF JAX-WS前端支持implementation("org.slf4j:slf4j-reload4j:2.1.0-alpha1") // 使用Reload4J作为SLF4J的后端日志实现}// 输出字符集为UTF-8
tasks.withType<JavaExec> {jvmArgs = listOf("-Dfile.encoding=UTF-8","-Dsun.stdout.encoding=UTF-8","-Dsun.stderr.encoding=UTF-8")
}// 编译时使用UTF-8字符集
tasks.withType<JavaCompile> {options.encoding = "UTF-8"
}

maven形式

<!-- pom.xml --><project><!-- ... --><dependencies><!-- 测试依赖配置 --><dependency><groupId>org.junit</groupId><artifactId>junit-bom</artifactId><version>5.9.1</version><type>pom</type><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.1</version><scope>test</scope></dependency><!-- 主要依赖配置 --><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>4.0.5</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>jakarta.activation</groupId><artifactId>jakarta.activation-api</artifactId><version>2.1.3</version></dependency><dependency><groupId>jakarta.jws</groupId><artifactId>jakarta.jws-api</artifactId><version>3.0.0</version></dependency><dependency><groupId>jakarta.xml.ws</groupId><artifactId>jakarta.xml.ws-api</artifactId><version>4.0.1</version></dependency><dependency><groupId>jakarta.xml.bind</groupId><artifactId>jakarta.xml.bind-api</artifactId><version>4.0.1</version></dependency><!-- Apache CXF相关依赖 --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http-jetty</artifactId><version>4.0.4</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>4.0.4</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-reload4j</artifactId><version>2.1.0-alpha1</version></dependency></dependencies><!-- ... -->
</project>
java">import jakarta.jws.WebService;@WebService // Webservice注解表明是一个Webservice的服务类(targetNamespace = "http://hacoj.com/mywebservice") // 指定服务的命名空间
public interface HelloService { // 接口名一样String sayHello(String name); // 方法定义名一样
}
java">/*** 客户端调用类,用于通过JAX-WS代理方式访问HelloService Web服务。*/
public class Client {/*** 程序主入口方法。** @param args 命令行参数*/public static void main(String[] args) {// 创建JAX-WS代理工厂对象JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();// 设置要访问的服务地址jaxWsProxyFactoryBean.setAddress("http://localhost:8899/ws/hello");// 设置服务接口类,即HelloServicejaxWsProxyFactoryBean.setServiceClass(HelloService.class);// 使用工厂对象创建HelloService接口的代理实例HelloService helloService = jaxWsProxyFactoryBean.create(HelloService.class);System.out.println(helloService.getClass());// 调用代理实例的方法,向服务端发送请求,并打印返回结果System.out.println(helloService.sayHello("hacoj"));}
}

结果如下

class jdk.proxy2.$Proxy36
Hello, hacoj!

深入了解

返回自定义的数据类

直接定义,在Server,Client定义一样的类即可

WebService注解与WebMethod注解

@WebService 注解支持若干属性,用于定制服务的相关特性。主要属性及其作用:

  1. name
  • 作用:指定Web服务的全局唯一标识(endpoint name)。这个名称通常用于客户端调用时构造服务URL的一部分。
  • 类型:String
  • 默认值:如果不显式设置,会根据类名和服务发布时的配置自动生成。
  1. targetNamespace
  • 作用:定义Web服务的命名空间(namespace),用于在WSDL(Web Services Description Language)文档中标识服务及其元素。
  • 类型:String
  • 默认值:如果没有指定,可能会根据服务发布的上下文自动确定,或者使用默认值(如不带前缀的类名)。
  1. serviceName
  • 作用:指定Web服务在WSDL文档中的服务名。这对于当WSDL由多个端点组成的服务(例如,具有多个接口实现的单个服务)尤其有用,可以明确区分各个端点的服务名。
  • 类型:String
  • 默认值:如果不指定,服务名通常根据类名生成。
  1. portName
  • 作用:指定Web服务端口在WSDL文档中的名称。端口定义了服务的访问点,包括绑定协议和地址信息。
  • 类型:String
  • 默认值:如果不指定,端口名通常根据类名和方法名生成。
  1. endpointInterface
  • 作用:
    endpointInterface 属性接收一个字符串值,该值是服务接口的完全限定类名。这个接口定义了服务对外提供的操作(方法)签名和契约。当您在服务实现类上使用 @WebService 注解并指定了 endpointInterface 时,意味着:
    服务实现类必须实现该接口:服务实现类(如 MyWebService)必须实现您在 endpointInterface 中指定的接口(如 com.hacoj.springwebservice.service.MyWebService)。这意味着服务实现类需要提供接口中所有方法的具体实现。
    接口方法作为Web服务操作:接口中声明的所有公有方法(通常带有 @WebMethod 注解)将作为Web服务对外提供的操作。客户端可以通过这些操作与服务进行交互。接口方法的签名(包括参数类型、返回类型和异常)决定了SOAP消息的结构和交互模式。
  • 类型:Class<?>
  • 默认值:如果不指定,JAX-WS会自动生成一个基于类中公共非静态方法的SEI。
  1. wsdlLocation
  • 作用:提供一个指向WSDL文件的URL或路径。这个属性允许开发者指定一个预先存在的WSDL文件,用于替代JAX-WS自动生成的WSDL。这对于已经存在WSDL设计或者需要严格遵循特定WSDL规范的场景非常有用。
  • 类型:String
  • 默认值:如果不指定,JAX-WS会自动生成WSDL文件。

示例

java">@WebService(name = "MyWebService",targetNamespace = "http://hacoj.com/mywebservice",serviceName = "MyWebServiceService",portName = "MyWebServicePort",endpointInterface = "com.hacoj.springwebservice.service.MyWebService"
)
public interface MyWebService {@WebMethodString sayHello(@WebParam(name = "id")String name);@WebMethod(operationName = "getModel")@WebResult(name = "result")SimpleModel getSimpleModel(String name);
}

@WebService 注解通常与 @WebMethod、@WebResult、@WebParam 等其他JAX-WS注解一起使用,以精细控制服务操作、参数和结果的映射。

此时如果你还在使用原来的Client,会报错

Caused by: org.apache.cxf.binding.soap.SoapFault: Unmarshalling Error: 意外的元素 (uri:“”, local:“arg0”)。所需元素为<{}id>

这时修改为一下内容就会正常进行

java">
@WebService(targetNamespace = "http://hacoj.com/mywebservice")
public interface HelloService {@WebMethodString sayHello(@WebParam(name = "id") String name); // 通过注解指定id@WebMethod()@WebResult(name = "result") SimpleModel getModel(String name); // 直接改名字,使得它与服务端的@WebMethod(operationName = "getModel")对应
}

SpringBus起什么作用?

SpringBus通常与Spring Web Service结合使用更多

SpringBus 是Apache CXF框架中一个核心组件,用于管理和配置CXF运行时环境。在集成Spring框架的应用中,SpringBus扮演着至关重要的角色,它将CXF的基础设施与Spring的依赖注入(DI)、生命周期管理等功能紧密结合起来,使得CXF服务的配置、发布、管理更加方便且符合Spring编程模型。

SpringBus的主要特点和作用

  • CXF上下文管理: SpringBus充当CXF内部的上下文容器,类似于Spring的ApplicationContext。它存储和管理CXF服务相关的各种对象,如服务端点(Endpoints)、数据绑定器(DataBinders)、拦截器(Interceptors)、消息处理器(MessageHandlers)等。通过SpringBus,这些组件能够共享配置、协作处理请求,并遵循统一的生命周期规则。

  • 与Spring集成: SpringBus无缝集成了Spring框架,允许CXF服务和其他组件以Spring Beans的形式存在。这意味着你可以利用Spring的依赖注入、AOP(面向切面编程)、事务管理、资源管理等特性来配置和管理CXF服务。例如,你可以使用@Autowired注解来注入CXF服务实例,或使用@Bean注解在Spring配置类中定义CXF相关的组件。

  • 配置加载: SpringBus可以加载并解析CXF的配置信息,无论是从Spring的XML配置文件、Java配置类还是从特定的CXF配置文件(如cxf.xml)。这些配置可能包括服务端点的地址、绑定、安全设置、拦截器链等。通过SpringBus,这些配置可以与Spring的其他应用配置一起管理,形成统一的应用配置体系。

  • 服务发布与注册: 在使用CXF发布Web服务时,通常会创建一个Endpoint对象,并将其与SpringBus关联。这样做可以使服务端点获得SpringBus提供的上下文支持。此外,SpringBus还可以帮助管理服务端点的生命周期,如发布、更新、撤销等操作。


http://www.ppmy.cn/server/6307.html

相关文章

Sulley入门教学——简介、安装(Win7、VMware)

1、简介 Sulley 是由 Pedram Amini 和 Aaron Portnoy 开发的开源工具。它以 Python 编写&#xff0c;可以轻松地在不同平台上部署和使用。Sulley 提供了一个灵活且功能强大的框架&#xff0c;允许用户定义协议消息的结构、字段类型、边界条件和模糊测试策略。用户可以使用 Sul…

【SpringBoot】Spring Boot 项目中整合 MyBatis 和 PageHelper

目录 前言 步骤 1: 添加依赖 步骤 2: 配置数据源和 MyBatis 步骤 3: 配置 PageHelper 步骤 4: 使用 PageHelper 进行分页查询 IDEA指定端口启动 总结 前言 Spring Boot 与 MyBatis 的整合是 Java 开发中常见的需求&#xff0c;特别是在使用分页插件如 P…

【单调栈】力扣85.最大矩形

好久没更新了 ~ 我又回来啦&#xff01; 两个好消息&#xff1a; 我考上研了&#xff0c;收到拟录取通知啦&#xff01;开放 留言功能 了&#xff0c;小伙伴对于内容有什么疑问可以在文章底部评论&#xff0c;看到之后会及时回复大家的&#xff01; 前面更新过的算法&#x…

EXCEL VBA限制工作数据批号或者自定义规则完整

EXCEL VBA限制工作数据批号或者自定义规则完整 Private Sub Worksheet_Change(ByVal Target As Range)Dim nRow%, Arr(), cMc$, cPc$, cTxt$, nSum!If Target.Row 1 Or Target.Column <> 4 Then Exit SubIf Target.CountLarge > 1 Then Exit SubcMc Target.Offset(0…

基于Hadoop的石油大数据平台设计

基于Hadoop的石油大数据平台设计 Design of an oil big data platform based on Hadoop 完整下载链接:基于Hadoop的石油大数据平台设计 文章目录 基于Hadoop的石油大数据平台设计摘要第一章 绪论1.1 研究背景1.2 研究意义1.3 国内外研究现状1.4 本文研究内容与结构 第二章 Ha…

Java快速排序知识点(含面试大厂题和源码)

快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;采用分治法&#xff08;Divide and Conquer&#xff09;的策略来对一个数组进行排序。快速排序的平均时间复杂度为 O(n log n)&#xff0c;在最坏的情况下为 O(n^2)&#xff0c;但这种情况很少发生…

【php快速上手(十一)】

目录 PHP快速上手&#xff08;十一&#xff09;PHP 连接数据库和创建数据库PHP 连接数据库使用 MySQLi连接 MySQL 数据库使用 PDO 连接 MySQL 数据库 PHP创建数据库使用MySQLi创建MySQL数据库&#xff1a;使用PDO创建MySQL数据库&#xff1a; PHP快速上手&#xff08;十一&…

【重生之我在学Android原生】Media3

前言 内容颇多&#xff0c;尽量从简 ExoPlayer使用 官方文档 参考文章 实现效果 Android&#xff08;java&#xff09; 使用ExoPlayer播放视频&#xff0c;自定义ExoPlayer界面&#xff0c;记录播放位置&#xff08;横屏竖屏切换/切换至后台等&#xff09; 案例实现 创建…