SpringBoot调用第三方WebService接口的两种实现方式

这篇具有很好参考价值的文章主要介绍了SpringBoot调用第三方WebService接口的两种实现方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

WebService简介

WebService接口的发布通常一般都是使用WSDL(web service descriptive language)文件的样式来发布的,该文档包含了请求的参数信息,返回的结果信息,我们需要根据WSDL文档的信息来编写相关的代码进行调用WebService接口。接下来我将采用常见的两种方式调用WebService接口。


场景描述

目前我需要使用java调用C#系统的一个WebService接口,传递参数为一个表号,返回的是一个Xml的数据类型,需要实现调用接口,获取到xml之后并解析为Json格式数据,并返回给前端。Java调用WebService接口,需要根据提供接口方的XSD文档编写相关代码,Xsd文档可以直接通过提供的接口地址进行查看。


WebServiceTemplate调用WebService接口实现

1.导入相关的依赖包,如下:

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
  </dependency>

2.使用WebServiceTemplate实现调用WebService接口,需要编写先关的解析类,根据提供的XSDL文档编写先关代码,XSDL文档信息如下:

POST /rootServiceFlow/EBoardService.asmx HTTP/1.1
Host: 10.200.0.74
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/AAFlow002x"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
   <AAFlow002x xmlns="http://tempuri.org/">
     <LotNo>string</LotNo>
   </AAFlow002x>
 </soap:Body>
</soap:Envelope>

上面的信息是包含请求所需要传递的参数,字段为LotNo。接下来XSDL的文档信息为返回的数据格式,如下:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <AAFlow002xResponse xmlns="http://tempuri.org/">
      <AAFlow002xResult>string</AAFlow002xResult>
    </AAFlow002xResponse>
  </soap:Body>
</soap:Envelope>

需要根据以上信息编写请求类AAFlow002x,响应接收解析类AAFlow002xResponse,和ObjectFactory类,这三个类可以使用Idea的终端通过命令的方式生成对应的java类,也可以通过自己编写生成java类。通过命令的方式如下:

xjc -d /path/to/output http://example.com/sample.xsd

/path/to/output为生成类的目录,http://example.com/sample.xsd为webServce的接口地址,生成的类如下:

AAFlow002x类编写如下:

import lombok.Data;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "",  propOrder = {
        "LotNo"
})
@XmlRootElement(name = "AAFlow002x", namespace = "http://tempuri.org/")
@Data
public class AAFlow002x {
    @XmlElement(name = "LotNo", namespace = "http://tempuri.org/", required = true)
    protected String LotNo;
}
AAFlow002xResponse类编写如下:


import lombok.Data;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AAFlow002xResponse", namespace = "http://tempuri.org/", propOrder = {
        "AAFlow002xResult"
})
@XmlRootElement(name = "AAFlow002xResponse")
@Data
public class AAFlow002xResponse {
    @XmlElement(name = "AAFlow002xResult", namespace = "http://tempuri.org/", required = true)
    private String AAFlow002xResult;
}

ObjectFatoty类编写如下:

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;

@XmlRegistry
public class ObjectFactory {
    private final static QName _AAFlow002_QNAME = new QName("http://tempuri.org/", "AAFlow002x");
    private final static QName _AAFlow002Response_QNAME = new QName("http://tempuri.org/", "AAFlow002xResponse");

    public ObjectFactory() {
    }

    public AAFlow002x createAAFlow002x() {
        return new AAFlow002x();
    }

    public AAFlow002xResponse createAAFlow002xResponse() {
        return new AAFlow002xResponse();
    }

    @XmlElementDecl(namespace = "http://tempuri.org/", name = "AAFlow002x")
    public JAXBElement<AAFlow002x> createAAFlow002x(AAFlow002x value) {
        return new JAXBElement<AAFlow002x>(_AAFlow002_QNAME, AAFlow002x.class, null, value);
    }

    @XmlElementDecl(namespace = "http://tempuri.org/", name = "AAFlow002yResponse")
    public JAXBElement<AAFlow002xResponse> createAAFlow002yResponse(AAFlow002xResponse value) {
        return new JAXBElement<AAFlow002xResponse>(_AAFlow002Response_QNAME, AAFlow002xResponse.class, null, value);
    }
}

编写使用WebServiceTemplate进行调用

@Service
@Slf4j
public class TestWebService {
 
    private static final String ENDPOINT_URL = "这里填写你调用的WebService接口地址";
    private static final String SOAP_ACTION = "http://tempuri.org/AAFlow002x";
    
    public  String  getDataTable(String LotNo) {
         //         创建WebServiceTemplate对象
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // 设置解析类,这里填写包的路径为AAFlow002xResponse类所在路径
        marshaller.setContextPath("org.test.parse");
        webServiceTemplate.setMarshaller(marshaller);
        webServiceTemplate.setUnmarshaller(marshaller);
        // 封装请求参数
        AAFlow002x aaFlow002 = new ObjectFactory().createAAFlow002x();
        aaFlow002.setLotNo("22113102");

        // 创建SOAP请求回调对象,这里的SOAP_ACTION指定你调用的接口的哪个方法
        SoapActionCallback soapActionCallback = new SoapActionCallback(SOAP_ACTION);

        // 调用WebService接口,发送请求并返回数据
        JAXBElement<AAFlow002xResponse> aaFlow002xResponse = (JAXBElement<AAFlow002xResponse>) webServiceTemplate.marshalSendAndReceive(ENDPOINT_URL, aaFlow002, soapActionCallback);
        String result = aaFlow002xResponse.getValue().getAAFlow002xResult();
        // 输出响应结果
        System.out.println(aaFlow002xResponse.getValue().getAAFlow002xResult());
        return result;
         }
    }

编写完成之后,Debug启动项目。出现如下图所示证明调用接口成功:
springboot 注解调用webservice,spring boot,java,后端

我们可以针对以上代码进行优化,写一个WebServiceConfig类,专门对WebServiceTemplate进行配置,这里就不在赘述。
采用WebServiceTemplate接口调用WebService接口,虽然可以采用命令的方式生成对应的Java代码,但是其缺点是如果请求的参数和返回的参数数据结构很复杂,生成的java类代码就很复杂。


HttpClientBuilder调用WebService接口实现

  @Override
    public JSONObject getDataFromMESSystem(String deviceNumber)  {
       // 根据上面的XSDL文档封装请求参数
       String strParameter = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
               "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
               "  <soap:Body>\n" +
               "    <AAFlow002y xmlns=\"http://tempuri.org/\">\n" +
               "  <LotNo>" + deviceNumber + "</LotNo>\n" +
               "    </AAFlow002y>\n" +
               "   </soap:Body>\n" +
               " </soap:Envelope>";

        // 获取数据,返回的是一个xml格式数据
        String xmlData = doPostSoap(UrlConstant.MES_SERVICE_URL, strParameter, UrlConstant.MES_SOAP_URI);
        JSONObject jsonObject = null;
        try {
            // 将请求结果转换成json类型
            if(StringUtils.isNotBlank(xmlData)){
                jsonObject = xml2Json(xmlData);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

/**
     * 发送Soap请求,并返回数据
     * @param url  WebService接口地址
     * @param soap 封装的请求参数
     * @param SOAPAction 对应的调用方法uri
     * @return 返回xml数据,用一个字符串接收
     */
    public static String doPostSoap(String url, String soap, String SOAPAction) {
        // 请求体
        String retStr = "";
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
            httpPost.setHeader("SOAPAction", SOAPAction);
            StringEntity data = new StringEntity(soap,
                    Charset.forName("UTF-8"));
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient
                    .execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印响应内容
                retStr = EntityUtils.toString(httpEntity, "UTF-8");
                System.err.println("response:" + retStr);
            }
            // 释放资源
            closeableHttpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retStr;
    }

接下来需要根据返回的xml格式数据解析为Json格式,我们可以用Postman测试WebService接口,查看数据返回格式,如下图所示:
springboot 注解调用webservice,spring boot,java,后端
点击Send,返回的数据格式如下图所示:
springboot 注解调用webservice,spring boot,java,后端
数据太多,这里我给出返回的缩减的结构数据,如下

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <AAFlow002yResponse xmlns="http://tempuri.org/">
            <AAFlow002yResult>
                <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="AAFlow002" msdata:UseCurrentLocale="true">
                        <xs:complexType>
                            <xs:choice minOccurs="0" maxOccurs="unbounded">
                                <xs:element name="AAFlow002">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:element name="F1000" type="xs:string" minOccurs="0" />
                                        </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                            </xs:choice>
                        </xs:complexType>
                    </xs:element>
                </xs:schema>
                <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                    <DocumentElement xmlns="">
                        <AAFlow002 diffgr:id="AAFlow0021" msdata:rowOrder="0">
                                                   <F1000>2596</F1000>
                        </AAFlow002>
                    </DocumentElement>
                </diffgr:diffgram>
            </AAFlow002yResult>
        </AAFlow002yResponse>
    </soap:Body>
</soap:Envelope>

根据上面的信息,编写解析xml数据转换为Json格式数据代码如下:


 /**
     * 解析webservice的返回结果,将xml解析为json格式数据
     * @param xmlStr xml内容
     * @return
     */
    public static JSONObject xml2Json(String xmlStr) throws DocumentException {

        Document doc = DocumentHelper.parseText(xmlStr);
        Element root = doc.getRootElement();
        Element body = root.element("Body");
        Element response = body.element("AAFlow002yResponse");
        Element result = response.element("AAFlow002yResult");
        Element diffgram = result.element(new QName("diffgram", Namespace.get("urn:schemas-microsoft-com:xml-diffgram-v1")));
        Element documentElement = diffgram.element("DocumentElement");
        Element aaFlow002 = documentElement.element("AAFlow002");
        JSONObject jsonObject = new JSONObject();
        Iterator<Element> iterator = aaFlow002.elementIterator();
        while (iterator.hasNext()) {
            Element element = iterator.next();
            jsonObject.put(element.getName(), element.getText());
        }
        return jsonObject;
    }

通过HttpClient的方式调用WebService接口,缺点是需要自己编写解析xml的代码,而WebServiceTemplate的方式可以自动解析为对应的Java类,但是个人更偏向于使用HttpClient的方式调用WebService接口,WebServiceTemplate方式,代码复杂度比较高,耦合性太强。文章来源地址https://www.toymoban.com/news/detail-518488.html

到了这里,关于SpringBoot调用第三方WebService接口的两种实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Forest-声明式HTTP客户端框架-集成到SpringBoot实现调用第三方restful api并实现接口数据转换

    Forest-声明式HTTP客户端框架-集成到SpringBoot实现调用第三方restful api并实现接口数据转换

    声明式HTTP客户端API框架,让Java发送HTTP/HTTPS请求不再难。它比OkHttp和HttpClient更高层, 是封装调用第三方restful api client接口的好帮手,是retrofit和feign之外另一个选择。 通过在接口上声明注解的方式配置HTTP请求接口。 官网: Forest   代码地址: forest: 声明式HTTP客户端API框架,让

    2024年02月04日
    浏览(12)
  • 仅仅是调用第三方接口那么简单吗?

    仅仅是调用第三方接口那么简单吗?

    最近有个项目需要本地处理之后,然后调用第三方接口,本来开始觉得很简单得事情,不就是调用第三方接口吗?但是却一波三折。 首先有了下面的第一版的设计。 这个设计很简单,也是最容易想到的。主要有下面几步 1、本地处理; 2、调用第三方接口; 3、本地日志打印

    2024年02月06日
    浏览(5)
  • 我调用第三方接口遇到的13大坑

    我调用第三方接口遇到的13大坑

    在实际工作中,我们经常需要在项目中调用第三方API接口,获取数据,或者上报数据,进行数据交换和通信。 那么,调用第三方API接口会遇到哪些问题?如何解决这些问题呢? 这篇文章就跟大家一起聊聊第三方API接口的话题,希望对你会有所帮助。   一般我们在第一次对接

    2023年04月16日
    浏览(8)
  • Java调用第三方http接口的常用方式

    前言 一、通过JDK网络类Java.net.HttpURLConnection 二、通过apache common封装好的HttpClient 三、通过Spring的RestTemplate 总结 今天项目需要接口互相调用,就看了一下这几个调用的方式 通过java.net包下的原生java.api提供的http请求 使用步骤: 通过统一的资源定位器(java.net.URL)获取连接器(java.

    2024年02月08日
    浏览(12)
  • 借助HttpWebRequest 调用第三方接口,获取Token和数据

    1、传入语句获取数据 2、获取token 3、获取设置身份认证及请求超时时间 4、在我使用的时候出现了下面的错误,通过查找是证书的问题,因为客户的web访问使用的IP地址访问,所以在代码中要加入跳过ssl验证的一行代码

    2024年03月18日
    浏览(12)
  • JAVA调用第三方接口的GET/POST/PUT请求方式

    GET请求 POST请求 POST请求(JSON传参) PUT请求(传TOKEN)

    2024年02月03日
    浏览(13)
  • Java以form-data(表单)的形式调用第三方接口

    Java以form-data(表单)的形式调用第三方接口

    之前写的调用第三方接口: Java使用原生API调用第三方接口 但是其中只包含了简单的接口(传递数据为JSON)调用。也就是 Content-Type 的值是设置成: 当第三方接口需要包含 文件 类型的参数,我们要设置成以 表单形式 提交,就要那么该属性就应该设置成 表示是以 表单形式

    2024年02月02日
    浏览(9)
  • SpringBoot中 如何优雅的 重试调用 第三方API?

    SpringBoot中 如何优雅的 重试调用 第三方API?

    引言 在实际的应用中,我们经常需要调用第三方API来获取数据或执行某些操作。然而,由于网络不稳定、第三方服务异常等原因,API调用可能会失败。为了提高系统的稳定性和可靠性,我们通常会考虑实现重试机制。 本文将深入探讨如何在Spring Boot项目中优雅地重试调用第三

    2024年01月21日
    浏览(12)
  • feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务

    最近接手一个项目,各子工程之间通过feign调用;各服务部署在K8S上,通过nacos管理配置;由于服务部署的机器无法开放端口等原因,导致本机服务与测试环境网络端口无法互通,故需要重写feign的调用地址;个人总结的方法有以下几种: 目录  第一种:feignclient配置URL 第二种

    2024年02月04日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包