Webservice使用

devtools/2024/10/15 5:18:59/

Webservice使用教程

Webservice的交互模式是一个类似于CS结构的模式,因此它需要一个Server端与一个Client端。在Client端访问Server端的接口来实现Webservice的功能。

Server端

打开IDEA创建gradle模块

webservice-01-server1

然后再build.gradle.kts文件中添加以下内容:


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"
}
<!-- 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>

在完成依赖配置后,我们来编写服务端的实现代码。
我们需要三个类来完成最基本的服务端的搭建

  1. 接口定义类:定义服务端的接口,用于客户端调用。
  2. 实现类:实现接口定义的服务端功能。
  3. 服务端启动类:启动服务端,并发布服务。
java">import jakarta.jws.WebService;@WebService // Webservice注解表明是一个Webservice的服务类
public interface HelloService {String sayHello(String name); // 方法定义
}
java">// 实现类
public class HelloServiceImpl implements HelloService {@Overridepublic String sayHello(String name) {return name + ", Hello!";}
}
java">import org.apache.cxf.feature.LoggingFeature;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;/*** 服务器启动类,负责发布基于CXF的HelloService Web服务。*/
public class Server {/*** 程序主入口** @param args 命令行参数*/public static void main(String[] args) {// 创建发布服务的工厂对象JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();// 设置服务地址factoryBean.setAddress("http://localhost:8899/ws/hello");// 设置服务实现类factoryBean.setServiceBean(new HelloServiceImpl());// 添加日志记录特性,以便记录服务交互过程中的请求与响应信息,虽然过时了,但是不影响使用factoryBean.getFeatures().add(new LoggingFeature());// 使用工厂对象发布服务factoryBean.create();}
}

还需要一个log4j的配置文件(放在resource目录下)这样不会报警

 # Root logger configurationlog4j.rootLogger=INFO, stdout# Console appenderlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n# Jetty logger specific configurationlog4j.logger.org.eclipse.jetty.util.component.ContainerLifeCycle=DEBUG, jettyLoglog4j.additivity.org.eclipse.jetty.util.component.ContainerLifeCycle=false# Jetty file appenderlog4j.appender.jettyLog=org.apache.log4j.FileAppenderlog4j.appender.jettyLog.File=log/jetty.loglog4j.appender.jettyLog.layout=org.apache.log4j.PatternLayoutlog4j.appender.jettyLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

然后启动一下Server的main方法,没有报错,服务端就启动了。
现在可以浏览器打开http://localhost:8899/ws/hello 查看是否运行中,也可以打开http://localhost:8899/ws/hello?wsdl 查看自动生成的wsdl文件。

Client端

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

  1. 接口定义类:定义客户端的接口,用于调用服务端的接口。
  2. 客户端启动类:启动客户端,并调用服务端的接口。
java">import jakarta.jws.WebService;@WebService // Webservice注解表明是一个Webservice的服务类
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.sayHello("hacoj"));}
}

启动一下Client的main方法,就可以调用服务端的接口了。
结果如下

Task :Client.main()
hacoj, Hello!

SOAP文件与WSDL文件

SOAP (Simple Object Access Protocol) 文件

SOAP (Simple Object Access Protocol) 文件,即简单对象访问协议(Simple Object Access Protocol)文件,是一种基于XML的协议,用于在Web服务中封装和传输请求与响应数据。

内容与格式
一个完整的SOAP文件通常包含以下组成部分:

SOAP Envelope

soap:Envelope 标签:表示整个SOAP消息的容器,是消息的根元素。
xmlns:soap 属性:定义SOAP命名空间(例如,http://www.w3.org/2003/05/soap-envelope),确保消息被正确解析。

SOAP Header

soap:Header 标签(可选):包含与消息正文(Body)内容相关的附加信息,如认证凭证、事务上下文、错误处理指示、路由信息等。

SOAP Body

soap:Body 标签:包含实际的请求或响应数据,即调用Web服务方法时传递的参数或返回的结果。
元素(或其对应的命名空间限定形式):表示正在调用的Web服务方法,通常对应于WSDL文件中定义的操作名。
参数或结果数据:作为子元素嵌套在操作名元素下,遵循WSDL定义的数据类型和结构。

SOAP Fault

soap:Fault 标签(可选):当发生错误时,在SOAP Body中包含错误信息,包括故障代码(fault code)、故障字符串(fault string)、故障详情(detail)等。

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>No binding operation info while invoking unknown method with params unknown.</faultstring></soap:Fault></soap:Body>
</soap:Envelope>

WSDL (Web Services Description Language) 文件

WSDL (Web Services Description Language) 文件,即Web服务描述语言文件,是一种基于XML的语言,用于描述Web服务的接口、操作、消息等。

内容与格式

Definitions

wsdl:definitions 标签:作为WSDL文档的根元素,包含所有其他元素。
targetNamespace 属性:定义WSDL文档所使用的命名空间,确保元素名称的唯一性。

Types

wsdl:types 标签:声明服务所使用的数据类型,通常采用XML Schema(XSD)定义复杂的结构化数据。

Message

wsdl:message 标签:定义Web服务交互中交换的消息结构,包括消息名称和消息部分(part)。

PortType

wsdl:portType 标签:定义Web服务接口(也称作契约),包括一组抽象操作(operation),每个操作描述了输入消息、输出消息和可能的故障消息。

Binding

wsdl:binding 标签:指定如何将抽象接口(PortType)绑定到具体的传输协议和数据格式,如SOAP、HTTP、MIME等。

Service

wsdl:service 标签:定义一个或多个服务端点(endpoint),每个端点关联一个或多个具体绑定(binding)和网络地址(location),以便客户端定位和访问服务。

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:tns="http://impl.service.hacoj.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://service.hacoj.com/"name="HelloServiceImplService" targetNamespace="http://impl.service.hacoj.com/">
<wsdl:import location="http://localhost:8899/ws/hello?wsdl=HelloService.wsdl"namespace="http://service.hacoj.com/"></wsdl:import>
<wsdl:binding name="HelloServiceImplServiceSoapBinding" type="ns1:HelloService"><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="HelloServiceImplService"><wsdl:port binding="tns:HelloServiceImplServiceSoapBinding" name="HelloServiceImplPort"><soap:address location="http://localhost:8899/ws/hello"/></wsdl:port>
</wsdl:service>
</wsdl:definitions>

http://www.ppmy.cn/devtools/4594.html

相关文章

Day 14 网络协议

常见网络设备&#xff1a;交换机 路由器 中继器 多协议网关&#xff08;路由器的前身&#xff09; 交换机&#xff1a;用于连接统一网络的设备&#xff0c;实现内网设备通信。 从广义上分为&#xff1a;局域网交换机&#xff0c;广域网交换机 从网络构成分为&#xff1a;接…

对单片机的一点理解

前言 大一时学过一段时间的51单片机&#xff0c;后面就一直研究STM32和算法&#xff0c;最近工作搞51单片机有半年了&#xff0c;有一些自己的想法&#xff0c;跟公司的工程师也探讨了一些&#xff0c;结合聊天记录&#xff0c;写了这篇博客&#xff0c;希望对读者有帮助。 有…

SQLite数据库中JSON 函数和运算符(二十七)

返回&#xff1a;SQLite—系列文章目录 上一篇:维护SQLite的私有分支&#xff08;二十六&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 ​1. 概述 默认情况下&#xff0c;SQLite 支持 29 个函数和 2 个运算符 处理 JSON 值。还有两个表值函数可用于分解 JSON 字…

Python实现BOA蝴蝶优化算法优化LightGBM分类模型(LGBMClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝴蝶优化算法(butterfly optimization algorithm, BOA)是Arora 等人于2019年提出的一种元启发式智能算…

SS3D翻译

SS3D AbstractIntroductionRelated WorkFully-Supervised 3D Object DetectionWeakly/Semi-Supervised 3D Object DetectionSparsely-Supervised 2D Object Detection MethodOverall FrameworkArchitecture of DetectorMissing-Annotated Instance Mining Module 缺失注释实例挖…

数据结构,算法(一)--排序

排序 冒泡排序 两次for循环 一次循环可以将一个数据排好序&#xff0c;那两次for循环叠加就可以将整个数组的数据排好序。 //arr[i]>(<)arr[i1] 交换 ​ //走一轮用的代码 for(int i 0;i<arr.length-1;i){if(arr[i]>arr[i1]){//交换//并且要注意 i<arr.len…

数据库基本概念和SQL基本语句

数据库&#xff08;Database&#xff09;是按照数据结构来组织、存储和管理数据的仓库。在数据库中&#xff0c;数据通常以表格的形式存储&#xff0c;这些表格包含了行和列。行通常代表记录&#xff0c;而列代表记录中的不同字段。数据库的设计允许对数据进行高效地查询、更新…

C语言 | Leetcode C语言题解之第38题外观数列

题目&#xff1a; 题解&#xff1a; class Solution { public:string countAndSay(int n) {string s "1", ans "1";for (int i 2; i < n; i) {ans "";for (int j 0; j < int(s.size()); ) {int k j;while(k < int(s.size()) &am…