SpringBoot调用第三方WebService接口的两种实现方式
WebService简介
WebService接口的发布通常一般都是使用WSDL(web service descriptive language)文件的样式来发布的,该文档包含了请求的参数信息,返回的结果信息,我们需要根据WSDL文档的信息来编写相关的代码进行调用WebService接口。接下来我将采用常见的两种方式调用WebService接口。
场景描述
目前我需要使用java调用C#系统的一个WebService接口,传递参数为一个表号,返回的是一个Xml的数据类型,需要实现调用接口,获取到xml之后并解析为Json格式数据,并返回给前端。Java调用WebService接口,需要根据提供接口方的XSD文档编写相关代码,Xsd文档可以直接通过提供的接口地址进行查看。
WebServiceTemplate调用WebService接口实现
导入相关的依赖包,如下:
org.springframework.boot spring-boot-starter-web-services
使用WebServiceTemplate实现调用WebService接口,需要编写先关的解析类,根据提供的XSDL文档编写先关代码,XSDL文档信息如下:
POST /rootServiceFlow/EBoardService.asmx HTTP/1.1Host: 10.200.0.74Content-Type: text/xml; charset=utf-8Content-Length: lengthSOAPAction: "http://tempuri.org/AAFlow002x" string
上面的信息是包含请求所需要传递的参数,字段为LotNo。接下来XSDL的文档信息为返回的数据格式,如下:
HTTP/1.1 200 OKContent-Type: text/xml; charset=utf-8Content-Length: length string
需要根据以上信息编写请求类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/")@Datapublic 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")@Datapublic 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;@XmlRegistrypublic 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 createAAFlow002x(AAFlow002x value) { return new JAXBElement(_AAFlow002_QNAME, AAFlow002x.class, null, value); } @XmlElementDecl(namespace = "http://tempuri.org/", name = "AAFlow002yResponse") public JAXBElement createAAFlow002yResponse(AAFlow002xResponse value) { return new JAXBElement(_AAFlow002Response_QNAME, AAFlow002xResponse.class, null, value); }}
编写使用WebServiceTemplate进行调用
@Service@Slf4jpublic 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 = (JAXBElement) webServiceTemplate.marshalSendAndReceive(ENDPOINT_URL, aaFlow002, soapActionCallback); String result = aaFlow002xResponse.getValue().getAAFlow002xResult(); // 输出响应结果 System.out.println(aaFlow002xResponse.getValue().getAAFlow002xResult()); return result; } }
编写完成之后,Debug启动项目。出现如下图所示证明调用接口成功:
我们可以针对以上代码进行优化,写一个WebServiceConfig类,专门对WebServiceTemplate进行配置,这里就不在赘述。
采用WebServiceTemplate接口调用WebService接口,虽然可以采用命令的方式生成对应的Java代码,但是其缺点是如果请求的参数和返回的参数数据结构很复杂,生成的java类代码就很复杂。
HttpClientBuilder调用WebService接口实现
@Override public JSONObject getDataFromMESSystem(String deviceNumber) { // 根据上面的XSDL文档封装请求参数 String strParameter = "\n" + "\n" + " \n" + " \n" + " " + deviceNumber + " \n" + " \n" + " \n" + " "; // 获取数据,返回的是一个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; } 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接口,查看数据返回格式,如下图所示:
点击Send,返回的数据格式如下图所示:
数据太多,这里我给出返回的缩减的结构数据,如下
2596
根据上面的信息,编写解析xml数据转换为Json格式数据代码如下:
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 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://blog.csdn.net/m0_37742400/article/details/130691229
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341