Idea調(diào)用WebService的關(guān)鍵步驟和注意事項(xiàng)
前言
? WebService是一種基于網(wǎng)絡(luò)的技術(shù),它允許不同的應(yīng)用程序在互聯(lián)網(wǎng)上相互通信。要進(jìn)行WebService對(duì)接,以下是一些關(guān)鍵步驟和注意事項(xiàng):
一、理解WebService的基本概念
- 定義:WebService是一種基于標(biāo)準(zhǔn)化協(xié)議和格式的應(yīng)用程序接口(API),它使用XML和HTTP來(lái)進(jìn)行通信。
- 特點(diǎn):可以跨平臺(tái)、跨語(yǔ)言進(jìn)行數(shù)據(jù)傳輸和應(yīng)用程序集成。
二、獲取WSDL文件
- WSDL定義:WSDL是Web服務(wù)描述語(yǔ)言(Web Services Description Language)的縮寫(xiě),是一種基于XML的語(yǔ)言,用于描述Web服務(wù)的接口、方法和數(shù)據(jù)類(lèi)型。
- 獲取方式:通常,可以通過(guò)訪問(wèn)WebService的WSDL地址來(lái)獲取WSDL文件。WSDL地址通常以“.wsdl”結(jié)尾,例如:http://localhost:8082/web/services/weather?wsdl。
- Idea的操作過(guò)程,
首先建立一個(gè)webService文件夾在項(xiàng)目中

選擇此文件夾,點(diǎn)擊Tools中的XML webService,選擇Generate

輸入地址點(diǎn)擊確定就行

會(huì)生成多個(gè)類(lèi)和方法名就直接可以調(diào)用
三、閱讀和理解WSDL文件
- 服務(wù)定義:WSDL文件包含一個(gè)或多個(gè)服務(wù)定義,每個(gè)服務(wù)定義描述了一個(gè)或多個(gè)相關(guān)的操作,以及它們接受和返回的消息的格式。
- 命名空間:WSDL中的命名空間用于唯一標(biāo)識(shí)WSDL中包含的類(lèi)型、元素和消息。
- 操作和方法:WSDL文件還描述了Web服務(wù)的地址、協(xié)議和傳輸機(jī)制等信息,以及具體的操作和方法。
四、選擇對(duì)接測(cè)試工具或方式
- SOAP UI:一個(gè)流行的WebService測(cè)試工具,可以用于查看WebService的接口信息、發(fā)送請(qǐng)求和接收響應(yīng)。
- Postman:另一個(gè)常用的API測(cè)試工具,同樣可以用于WebService的對(duì)接測(cè)試。
- 編程方式:在代碼中,可以通過(guò)發(fā)送HTTP請(qǐng)求來(lái)調(diào)用WebService,請(qǐng)求參數(shù)需要按照WSDL文件中定義的格式封裝成XML格式。
五、發(fā)送請(qǐng)求和接收響應(yīng)
- 請(qǐng)求格式:根據(jù)WSDL文件中的定義,構(gòu)造符合要求的SOAP請(qǐng)求報(bào)文。請(qǐng)求報(bào)文通常包含Envelope(信封)、Header(頭部)和Body(正文)等部分。
- 發(fā)送請(qǐng)求:使用選擇的對(duì)接工具或方式發(fā)送請(qǐng)求到WebService的服務(wù)端點(diǎn)。
- 接收響應(yīng):服務(wù)端點(diǎn)接收到請(qǐng)求后,會(huì)進(jìn)行解析并調(diào)用相應(yīng)的Web服務(wù)方法,然后將結(jié)果封裝成HTTP響應(yīng)返回。響應(yīng)報(bào)文同樣遵循SOAP協(xié)議,并包含Envelope、Header和Body等部分。
六、直接通過(guò)xml和http請(qǐng)求訪問(wèn)
? 1. 引用包
<!--
使用apache的httpclient發(fā)送http,需要引入httpclient依賴(lài);
使用OMElement需要引入axis2-transport-http依賴(lài);改以來(lái)本身帶有httpclient依賴(lài),所以
我們不在需要單獨(dú)引入httpclient依賴(lài)了
-->
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.7.8</version>
</dependency>? 2.
package com.smart.util;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AbcAxis2DemoApplicationUtils {
public static String doPost(String partNo) throws IOException {
// webservice的wsdl地址
final String wsdlURL = ""
// 設(shè)置編碼。(因?yàn)槭侵苯觽鞯膞ml,所以我們?cè)O(shè)置為text/xml;charset=utf8)
final String contentType = "text/xml;charset=utf8";
/// 拼接要傳遞的xml數(shù)據(jù)(注意:此xml數(shù)據(jù)的模板我們根據(jù)wsdlURL從SoapUI中獲得,只需要修改對(duì)應(yīng)的變量值即可)
StringBuffer xMLcontent = new StringBuffer("");
xMLcontent.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:DefaultNamespace\">\n");
xMLcontent.append(" <soapenv:Header/>\n");
xMLcontent.append(" <soapenv:Body>\n");
xMLcontent.append(" <urn:字段1>Shanghai</urn:字段1>\n");
xMLcontent.append(" <urn:字段2>" + "TAN2921" + "</urn:字段2>\n");
xMLcontent.append(" </soapenv:Body>\n");
xMLcontent.append("</soapenv:Envelope>");
// 調(diào)用工具類(lèi)方法發(fā)送http請(qǐng)求
String responseXML = HttpSendUtil.doHttpPostByHttpClient(wsdlURL, contentType, xMLcontent.toString());
// 當(dāng)然我們也可以調(diào)用這個(gè)工具類(lèi)方法發(fā)送http請(qǐng)求
// String responseXML = HttpSendUtil.doHttpPostByRestTemplate(wsdlURL, contentType, xMLcontent.toString());
// 利用axis2的OMElement,將xml數(shù)據(jù)轉(zhuǎn)換為OMElement
OMElement omElement = OMXMLBuilderFactory
.createOMBuilder(new ByteArrayInputStream(responseXML.getBytes()), "utf-8").getDocumentElement();
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // 設(shè)置為true以處理命名空間
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(new StringReader(responseXML));
Document document = builder.parse(inputSource);
// 獲取所有名為"OUTPUT_SHIPTOPARTYReturn"的元素,并考慮命名空間
NodeList nodeList = document.getElementsByTagNameNS("urn:DefaultNamespace", "OUTPUT_SHIPTOPARTYReturn");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
// 檢查元素是否有文本內(nèi)容(即非空且非自閉合標(biāo)簽)
if (element.hasChildNodes() && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
String textContent = element.getTextContent();
System.out.println("Extracted value: " + textContent);
return textContent;
}
}
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
return null;
}
public static String getNodeValue(Document document, String nodePaht) {
XPathFactory xpfactory = XPathFactory.newInstance();
XPath path = xpfactory.newXPath();
String servInitrBrch = "";
try {
servInitrBrch = path.evaluate(nodePaht, document);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return servInitrBrch;
}
public static Document StringTOXml(String str) {
StringBuilder sXML = new StringBuilder();
sXML.append(str);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = null;
try {
InputStream is = new ByteArrayInputStream(sXML.toString().getBytes("utf-8"));
doc = dbf.newDocumentBuilder().parse(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
}
/**
* HTTP工具類(lèi)
*
* @author JustryDeng
* @DATE 2018年9月22日 下午10:29:08
*/
class HttpSendUtil {
/**
* 使用apache的HttpClient發(fā)送http
*
* @param wsdlURL
* 請(qǐng)求URL
* @param contentType
* 如:application/json;charset=utf8
* @param content
* 數(shù)據(jù)內(nèi)容
* @DATE 2018年9月22日 下午10:29:17
*/
static String doHttpPostByHttpClient(final String wsdlURL, final String contentType, final String content)
throws ClientProtocolException, IOException {
// 獲得Http客戶(hù)端(可以理解為:你得先有一個(gè)瀏覽器;注意:實(shí)際上HttpClient與瀏覽器是不一樣的)
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 創(chuàng)建Post請(qǐng)求
HttpPost httpPost = new HttpPost(wsdlURL);
StringEntity entity = new StringEntity(content.toString(), "UTF-8");
// 將數(shù)據(jù)放入entity中
httpPost.setEntity(entity);
httpPost.setHeader("Content-Type", contentType);
// 響應(yīng)模型
CloseableHttpResponse response = null;
String result = null;
try {
// 由客戶(hù)端執(zhí)行(發(fā)送)Post請(qǐng)求
response = httpClient.execute(httpPost);
// 從響應(yīng)模型中獲取響應(yīng)實(shí)體
// 注意:和doHttpPostByRestTemplate方法用的不是同一個(gè)HttpEntity
org.apache.http.HttpEntity responseEntity = response.getEntity();
System.out.println("響應(yīng)ContentType為:" + responseEntity.getContentType());
System.out.println("響應(yīng)狀態(tài)為:" + response.getStatusLine());
if (responseEntity != null) {
result = EntityUtils.toString(responseEntity);
System.out.println("響應(yīng)內(nèi)容為:" + result);
}
} finally {
// 釋放資源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
}
return result;
}
/**
* 使用springframework的RestTemplate發(fā)送http
*
* @param wsdlURL
* 請(qǐng)求URL
* @param contentType
* 如:application/json;charset=utf8
* @param content
* 數(shù)據(jù)內(nèi)容
* @DATE 2018年9月22日 下午10:30:48
*/
static String doHttpPostByRestTemplate(final String wsdlURL, final String contentType, final String content) {
// http使用無(wú)參構(gòu)造;https需要使用有參構(gòu)造
RestTemplate restTemplate = new RestTemplate();
// 解決中文亂碼
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
converterList.remove(1);
HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
converterList.add(1, converter);
restTemplate.setMessageConverters(converterList);
// 設(shè)置Content-Type
HttpHeaders headers = new HttpHeaders();
headers.remove("Content-Type");
headers.add("Content-Type", contentType);
// 數(shù)據(jù)信息封裝
// 注意:和doHttpPostByHttpClient方法用的不是同一個(gè)HttpEntity
org.springframework.http.HttpEntity<String> formEntity = new org.springframework.http.HttpEntity<String>(
content, headers);
String result = restTemplate.postForObject(wsdlURL, formEntity, String.class);
return result;
}
}
七、處理響應(yīng)結(jié)果
- 解析響應(yīng):將接收到的響應(yīng)報(bào)文進(jìn)行解析,提取出需要的數(shù)據(jù)。這通常涉及到對(duì)XML格式的響應(yīng)報(bào)文進(jìn)行解析和處理。
- 錯(cuò)誤處理:在對(duì)接過(guò)程中,可能會(huì)遇到各種錯(cuò)誤和異常情況。因此,需要添加適當(dāng)?shù)腻e(cuò)誤處理邏輯來(lái)應(yīng)對(duì)這些情況。
總結(jié)
到此這篇關(guān)于Idea調(diào)用WebService的關(guān)鍵步驟和注意事項(xiàng)的文章就介紹到這了,更多相關(guān)Idea調(diào)用WebService內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Java反射機(jī)制實(shí)現(xiàn)對(duì)象相同字段的復(fù)制操作
這篇文章主要介紹了利用Java反射機(jī)制實(shí)現(xiàn)對(duì)象相同字段的復(fù)制操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Maven項(xiàng)目讀取resources文件路徑問(wèn)題解決方案
這篇文章主要介紹了Maven項(xiàng)目讀取resources文件路徑問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
SpringBoot項(xiàng)目如何打war包問(wèn)題詳解
傳統(tǒng)的部署方式:將項(xiàng)目打成war包,放入tomcat的webapps目錄下面,啟動(dòng)tomcat,即可訪問(wèn).文中有非常詳細(xì)的介紹,對(duì)正在學(xué)習(xí)springboot的小伙伴很有幫助,需要的朋友可以參考下2021-05-05
java實(shí)現(xiàn)操作系統(tǒng)中的最佳置換Optimal算法
這篇文章主要介紹了java實(shí)現(xiàn)操作系統(tǒng)中的最佳置換Optimal算法 ,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
java并發(fā)編程synchronized底層實(shí)現(xiàn)原理
這篇文章主要介紹了java并發(fā)編程synchronized底層實(shí)現(xiàn)原理2022-02-02
Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type
這篇文章主要介紹了Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type的相關(guān)資料,需要的朋友可以參考下2017-05-05
List集合對(duì)象中按照不同屬性大小排序的實(shí)例
下面小編就為大家?guī)?lái)一篇List集合對(duì)象中按照不同屬性大小排序的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
Springboot Redis?哨兵模式的實(shí)現(xiàn)示例
本文主要介紹了Springboot Redis?哨兵模式的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

