使用java对接WebService接口实现过程

 更新时间:2026年04月01日 09:45:49   作者:大手你不懂  
文章介绍了WebService的概念、应用场景和对接方式,特别强调了Java中对接WebService的方法,包括JAX-WS、第三方库和Spring的WebServiceTemplate,还分享了使用Hutool工具的方法,并通过实例展示了服务端和客户端的实现,以及使用SoapUI进行验证和测试的过程

1、什么是WebService?

WebService是一个平台 独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。

Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。

Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。

Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。

Web Service减少了应用接口的花费。

Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。

2、WebService应用场景?

(1)异构系统(不同的开发语言)的整合:例如,在一个企业内部,可能有多个部门使用不同的系统和编程语言。通过使用Webservice,这些系统可以互相通信并共享数据。

(2)不同客户端的整合:例如,一个网站可能需要同时支持浏览器、手机端(Android/iOS)、微信等不同平台的访问。通过使用Webservice,可以在后端实现统一的数据处理和业务逻辑,并为不同客户端提供接口调用。

(3)软件集成和复用:例如,气 象 局可以通过Webservice向天气查询网站提供实时天气数据。这种情况下,气 象 局作为服务端,提供数据服务;天气查询网站作为客户端,通过调用Webservice来获取数据。

3、java怎么对接WebService呢?

在Java中,我们可以使用不同的方式来对接外部系统提供的Web服务接口。以下是几种常见的方法:

(1)使用JAX-WS(Java API for XML Web Services):JAX-WS是Java EE的一部分,它提供了一种简单但强大的方式来开发基于SOAP的Web服务。您可以使用wsimport工具来生成客户端代理代码,该代码可用于调用外部Web服务的方法。下面是一个简单的示例:

wsimport -s src -d build -p com.example http://www.example.com/YourService?wsdl

上述命令将根据WSDL文件生成客户端代码,并包含在指定的包中。一旦代码生成完成,您可以像在本地调用本地方法一样调用外部Web服务的方法。

(2)使用第三方库(例如CXF、Axis等):除了JAX-WS之外,还有许多第三方的Java Web服务库可以帮助您对接外部系统提供的Web服务接口。比如Apache CXF和Apache Axis都提供了强大的Web服务客户端和服务端库。您可以根据自己的喜好和需求选择合适的库进行开发。

在实际应用中,您需要考虑以下几点:

  • 安全性:外部Web服务接口可能需要认证,您需要了解如何在Java中处理认证信息,如用户名/密码、密钥等。
  • 异常处理:调用外部Web服务时可能会出现各种异常情况,例如网络中断、超时等。您需要了解如何在客户端代码中处理这些异常。
  • 数据传输格式:Web服务接口通常支持多种数据传输格式,如XML、JSON等。您需要了解如何在Java中处理这些数据格式。

(3)使用Spring框架提供的WebServiceTemplate类。WebServiceTemplate类提供了一种简单而灵活的方式来调用Web服务,并且集成了许多常见的Web服务调用需求,如消息处理、异常处理等。

import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

public class WebServiceClient {

    public static void main(String[] args) {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

        // 设置Web服务地址
        webServiceTemplate.setDefaultUri("http://www.example.com/YourService");

        // 设置编组器和解组器
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.example.yourpackage"); // 设置上下文路径,用于识别要编组/解组的类
        webServiceTemplate.setMarshaller(marshaller);
        webServiceTemplate.setUnmarshaller(marshaller);

        // 构造请求数据
        YourRequestObject request = new YourRequestObject();

        // 调用外部Web服务接口
        YourResponseObject response = (YourResponseObject) webServiceTemplate.marshalSendAndReceive(request);

        // 处理响应数据
        // ...
    }
}

在上述示例中,我们使用了Jaxb2Marshaller作为编组器和解组器,并设置了要编组/解组的目标类的上下文路径。您需要将"com.example.yourpackage"替换为实际的包路径,以便编组/解组器能够识别请求和响应对象。这个上下文路径通常是您生成的Web服务客户端代码的包路径。

但经过查找资料,并进行测试与尝试。我最终选择的是使用hutool工具包所提供的方法,我也推荐此方法。

3.1 自己编写一个WebService服务端

我这里方便测试,所以编写了一个服务端

3.1.1 代码

package com.webservice.server;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author ZhaoShuHao
 * @Date 2023/11/15 16:16
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User
{
    //姓名
    private String name;
    //性别
    private String sex;
    //年龄
    private int age;
}

package com.webservice.server;

/**
 * @Author ZhaoShuHao
 * @Date 2023/11/15 16:16
 */
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService(targetNamespace = "http://service.cn.com/")
public interface UserService
{

    /**
     * 1.在类上添加@WebService注解,代表发布一个WebService服务。
     * 2.给类添加上@WebService注解后,类中所有的非静态方法都将会对外公布。
     * 3.如果希望某个方法不对外公开,可以在方法上添加@WebMethod(exclude=true),阻止对外公开。
     * 4.如果一个类上,被添加了@WebService注解,则必须此类至少有一个可以公开的方法,否则将会启动失败。
     *   protected、private、final、static方法不能对外公开。
     * 5.@targetNamespace 设置命名空间,默认包名,取反
     */

    @WebMethod
    public User getUserInfo(@WebParam(name = "name", targetNamespace = "http://service.cn.com/") String name,
                            @WebParam(name = "sex", targetNamespace = "http://service.cn.com/") String sex,
                            @WebParam(name = "age", targetNamespace = "http://service.cn.com/") int age);

}
package com.webservice.server;

/**
 * @Author ZhaoShuHao
 * @Date 2023/11/15 16:17
 */
public class UserServiceImpl implements UserService
{
    @Override
    public User getUserInfo(String name,String sex,int age)
    {
        User user = new User(name,sex,age);
        return user;
    }
}

package com.webservice.server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

/**
 * @Author ZhaoShuHao
 * @Date 2023/11/15 16:18
 */
public class ServerTest
{
    public static void main(String[] args)
    {
        //发布服务的工厂
        JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
        //设置服务的地址
        factory.setAddress("http://127.0.0.1:9999/test");
        //设置服务类
        factory.setServiceBean(new UserServiceImpl());
        //发布服务
        factory.create();
        System.out.println(("发布服务成功,wsdl地址是:http://127.0.0.1:9999/test?wsdl"));
    }

}

3.1.2 运行结果

wsdl文件格式如下:

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://server.webservice.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://service.cn.com/" name="UserServiceImplService" targetNamespace="http://server.webservice.com/">
<wsdl:import location="http://127.0.0.1:9999/test?wsdl=UserService.wsdl" namespace="http://service.cn.com/"> </wsdl:import>
<wsdl:binding name="UserServiceImplServiceSoapBinding" type="ns1:UserService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getUserInfo">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUserInfo">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserInfoResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="UserServiceImplService">
<wsdl:port binding="tns:UserServiceImplServiceSoapBinding" name="UserServiceImplPort">
<soap:address location="http://127.0.0.1:9999/test"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

3.2 编写客户端

3.2.1代码

package com.webservice.client;

import cn.hutool.core.util.XmlUtil;
import cn.hutool.http.webservice.SoapClient;
import org.w3c.dom.Document;

import javax.xml.xpath.XPathConstants;

/**
 * @Author ZhaoShuHao
 * @Date 2023/11/15 16:20
 */
public class ClientTest
{
    public static void main(String[] args)
    {
        //设置webservice服务地址
        SoapClient client = SoapClient.create("http://127.0.0.1:9999/test?wsdl")
                // 设置要请求的方法,传入对应的命名空间
                .setMethod("getUserInfo", "http://service.cn.com/")
                // 设置参数
                .setParam("name", "张三")
                .setParam("sex", "男")
                .setParam("age", 23);
        // 发送请求,参数true表示返回一个格式化后的XML内容
        String result = client.send(true);
        System.out.println(result);
        System.out.println("----------------------------");
        // 返回内容为XML字符串,可以配合XmlUtil解析这个响应
        Document docResult = XmlUtil.readXML(result);
        Object name = XmlUtil.getByXPath("//return//name", docResult, XPathConstants.STRING);
        Object sex = XmlUtil.getByXPath("//return//sex", docResult, XPathConstants.STRING);
        Object age = XmlUtil.getByXPath("//return//age", docResult, XPathConstants.STRING);
        System.out.println("name = " + name);
        System.out.println("sex = " + sex);
        System.out.println("age = " + age);
    }
}

3.2.2 运行结果

3.3 使用图形化工具SoapUI进行测试

下载地址:The World’s Most Popular API Testing Tool | SoapUI

3.3.1 使用该工具的原因是什么?

我在开发过程中,遇到了用户提供的WebService接口是内网这种情况,而且只能是内网。所以用户只能提供堡垒机得形式,让我调用。那怎么验证我写的接口没问题呢?怎么快速确定用户的返回数据是什么呢?所以我先在本地模拟了一下WebService的客户端与服务端。并且在堡垒机上安装了SoapUI进行测试。确保用户和我的接口均没问题。

3.3.2 安装与使用

1、安装:没什么好说的,直接下一步即可

2、使用

(1)安装完成,页面大概是这样的

(2)我们直接开始调用WebService接口

点击SOAP菜单,输入一个名称(名称随意取)。输入wsdl的地址。点击ok。

左侧菜单出现一个文件夹,打开,双击最后一个

点击运行,在右侧还可以选择格式进行展示

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • RabbitMQ消息队列实现延迟任务示例

    RabbitMQ消息队列实现延迟任务示例

    这篇文章主要为大家介绍了RabbitMQ消息队列实现延迟任务示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Java实现数据脱敏的方法详细讲解

    Java实现数据脱敏的方法详细讲解

    这篇文章主要给大家介绍了关于Java实现数据脱敏的相关资料,数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护,需要的朋友可以参考下
    2023-06-06
  • 解决idea不显示Services工具栏的问题

    解决idea不显示Services工具栏的问题

    这篇文章主要介绍了解决idea不显示Services工具栏的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java四种常用线程池的详细介绍

    Java四种常用线程池的详细介绍

    今天小编就为大家分享一篇关于Java四种常用线程池的详细介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • SpringBoot实现不同接口指定上传文件大小的具体步骤

    SpringBoot实现不同接口指定上传文件大小的具体步骤

    这篇文章主要介绍了在Spring Boot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于接口自定义值,确保验证逻辑正确执行,需要的朋友可以参考下
    2025-08-08
  • Java多线程通讯之wait,notify的区别详解

    Java多线程通讯之wait,notify的区别详解

    这篇文章主要介绍了Java多线程通讯之wait,notify的区别详解,非常不错,具有一定的参考借鉴借鉴价值,需要的朋友可以参考下
    2018-07-07
  • spring应用中多次读取http post方法中的流遇到的问题

    spring应用中多次读取http post方法中的流遇到的问题

    这篇文章主要介绍了spring应用中多次读取http post方法中的流,文中给大家列举处理问题描述及解决方法,需要的朋友可以参考下
    2018-11-11
  • java如何分布式锁实现和选型

    java如何分布式锁实现和选型

    文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zookeeper的分布式锁实现示例,分析了每种方法的优点和缺点
    2025-01-01
  • Java反射机制,如何将一个实体类所有字段赋值为null

    Java反射机制,如何将一个实体类所有字段赋值为null

    这篇文章主要介绍了Java反射机制,如何将一个实体类所有字段赋值为null,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • SpringBoot全局异常处理方案分享

    SpringBoot全局异常处理方案分享

    这篇文章主要介绍了SpringBoot全局异常处理方案分享,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05

最新评论