Webservice使用

简介: Webservice使用

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. 服务端启动类:启动服务端,并发布服务。
import jakarta.jws.WebService;

@WebService // Webservice注解表明是一个Webservice的服务类
public interface HelloService {
   

    String sayHello(String name); // 方法定义
}
// 实现类
public class HelloServiceImpl implements HelloService {
   
    @Override
    public String sayHello(String name) {
   
        return name + ", Hello!";
    }
}
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 configuration
 log4j.rootLogger=INFO, stdout

 # Console appender
 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.Target=System.out
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

 # Jetty logger specific configuration
 log4j.logger.org.eclipse.jetty.util.component.ContainerLifeCycle=DEBUG, jettyLog
 log4j.additivity.org.eclipse.jetty.util.component.ContainerLifeCycle=false

 # Jetty file appender
 log4j.appender.jettyLog=org.apache.log4j.FileAppender
 log4j.appender.jettyLog.File=log/jetty.log
 log4j.appender.jettyLog.layout=org.apache.log4j.PatternLayout
 log4j.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. 客户端启动类:启动客户端,并调用服务端的接口。
import jakarta.jws.WebService;

@WebService // Webservice注解表明是一个Webservice的服务类
public interface HelloService {
    // 接口名一样

    String sayHello(String name); // 方法定义名一样
}
/**
 * 客户端调用类,用于通过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");

        // 设置服务接口类,即HelloService
        jaxWsProxyFactoryBean.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消息的容器,是消息的根元素。
xmlns:soap 属性:定义SOAP命名空间(例如,http://www.w3.org/2003/05/soap-envelope),确保消息被正确解析。

SOAP Header

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

SOAP Body

标签:包含实际的请求或响应数据,即调用Web服务方法时传递的参数或返回的结果。

元素(或其对应的命名空间限定形式):表示正在调用的Web服务方法,通常对应于WSDL文件中定义的操作名。
参数或结果数据:作为子元素嵌套在操作名元素下,遵循WSDL定义的数据类型和结构。

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文档的根元素,包含所有其他元素。
targetNamespace 属性:定义WSDL文档所使用的命名空间,确保元素名称的唯一性。

Types

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

Message

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

PortType

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

Binding

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

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>
目录
相关文章
|
缓存 监控 前端开发
优化前端性能:提升网页加载速度的10个技巧
在当今互联网时代,网页加载速度成为用户体验的重要指标之一。本文将介绍10个有效的技巧,帮助前端开发人员优化网页性能,提升用户的访问体验。
|
XML 前端开发 网络协议
WebService 教程(包含项目实践)
Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
WebService 教程(包含项目实践)
|
1月前
|
弹性计算 运维 Linux
OpenClaw 可以做什么?OpenClaw(Clawdbot)阿里云ECS+本地部署完整教程
OpenClaw(曾用名 Clawdbot、Moltbot)是一款开源、可自托管、以自然语言驱动任务执行的 AI 智能体框架,核心定位是把大模型从“只会聊天”升级为“能动手做事”的自动化助手。它不只是对话界面,而是具备文件操作、系统指令执行、浏览器自动化、定时任务、多渠道交互与插件扩展的一体化运行环境,支持云端长期稳定运行与本地私有化部署,兼顾可用性与数据安全。2026 年版本进一步优化了模型调度、内存占用与社区技能生态,可广泛用于个人效率提升、办公自动化、轻量开发运维、信息汇总与定时任务等场景。
1470 8
|
XML Java Maven
WebService客户端调用的5种常见方式
本文介绍了在Java中创建和调用WebService的方法,包括服务端的搭建、配置类的添加以及客户端的多种调用方式(如使用JDK原生代码、wsimport命令、动态调用、代理工厂及HttpClient)。文中详细展示了每种方法的实现步骤和示例代码,强调了服务端与客户端参数实体类字段的兼容性,并推荐使用代理工厂方式进行调用。
3713 0
WebService客户端调用的5种常见方式
|
9月前
|
消息中间件 SQL 供应链
如何开发供应商管理系统中的库存管理板块(附架构图+流程图+代码参考)
供应商管理系统(SMS)是企业供应链管理的核心工具,通过信息化手段实现从采购、入库、出库到库存盘点的全流程管理。系统以供应商为中心,整合订单、发货、验收、库存等环节,提升供应链协同效率。库存管理作为关键模块,通过入库单、出库单、调拨单和盘点等功能,实现库存数据的实时更新与可视化监控,有效避免缺货或积压风险。结合现代技术如Spring Boot、Vue3、MySQL等,系统具备高可用性与灵活扩展性,助力企业提升库存周转率与运营效率。
|
运维 监控 固态存储
|
机器学习/深度学习 物联网
可控文生图:EliGen控制实体的位置细节变化
为文生图模型增加额外的控制条件一直是AIGC社区研究的重点之一,如ControlNet, IP-Adapter等一直是热门可控生成方法。近期,魔搭社区联合浙江大学对实体级可控文生图进行了探索,并开发了EliGen模型。
483 11
|
机器学习/深度学习 人工智能 数据可视化
大数据时代的数据可视化技术:趋势、挑战与未来展望
【7月更文挑战第22天】随着技术的不断进步和应用场景的不断拓展,数据可视化技术将在更多领域发挥更大的作用。未来,我们可以期待更加智能化、实时化、沉浸式和民主化的数据可视化解决方案的出现。同时,随着数据量的不断增加和数据类型的不断丰富,数据可视化技术也将面临更多的挑战和机遇。只有不断创新和优化技术才能满足日益增长的需求并推动数据可视化技术的持续发展。
2038 3
|
存储 数据可视化 大数据
从零到一建设数据中台 - 应用场景及实施路径
从零到一建设数据中台 - 应用场景及实施路径
983 0
Java预览及打印PDF的三种方法
Java预览及打印PDF的三种方法
4866 1
Java预览及打印PDF的三种方法