報文(message)是網路中交換與傳輸的資料單元,即站點一次性要發送的資料塊,報文包含了將要發送的完整的資料資訊,其長短很不一致,長度不限且可變,
個人理解:從客戶端把字串寫入位元組陣列流中傳達至服務端,但是此字串是XML格式的,然后到了服務端,使用位元組陣列進行獲取該字串,再獲取該字串的document物件(因為字串是xml格式的),然后決議獲取資料即可,
文章目錄
- 發送報文
- 接收報文
- 決議報文
- 回傳報文
發送報文
先創建生成報文的方法,添加了xml資料
/**
* @desc 生成xml報文且轉換為字串
* @return
*/
public String xmlToString() {
StringBuffer sendStr = new StringBuffer();
// 以下為添加的xml資訊
sendStr.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
sendStr.append("<request_data>");
sendStr.append("<request_token>BCDBCD</request_token>");
sendStr.append("<request_cardNum>62284801912705</request_cardNum>");
sendStr.append("<request_name>張飛</request_name>");
sendStr.append("<request_pass>123123</request_pass>");
sendStr.append("<request_time>"+new Dates().CurrentYMDHSMTime()+"</request_time>");
sendStr.append("<monery_count>200.00</monery_count>");
sendStr.append("<shop_name>吉野家</shop_name>");
sendStr.append("<shop_id>JYJ</shop_id>");
sendStr.append("<sale_no>"+UUID.randomUUID().toString()+"</sale_no>");
sendStr.append("</request_data>");
// 創建字串用于回傳
String str = sendStr.toString();
return str;
}
將報文xml轉為流寫入
/**
* @desc 將xml轉為流寫入
* @param servletConnection
* @throws IOException
*/
public void xmlWriteStream(HttpURLConnection servletConnection) throws IOException {
// 創建流,寫入xml資料
OutputStream ouput = servletConnection.getOutputStream();
// 呼叫方法獲取xml字串
String str = xmlToString();
System.out.println(str);
// 將xml字串轉為btye陣列寫入流
ouput.write(str.getBytes("UTF-8"));
ouput.flush();// 重繪流
ouput.close();// 關閉流
}
創建客戶端與服務端的連接并且設定發送報文的一些屬性
/**
* @desc 創建客戶端與服務端的連接并且設定發送報文的一些屬性
* @return
* @throws IOException
*/
public HttpURLConnection cerateServletUrl() throws IOException {
// 服務端地址
URL uploadServlet = new URL("http://localhost:1023/BaoWenServer/xmlServlet.do");
// 創建連接
HttpURLConnection servletConnection = (HttpURLConnection) uploadServlet.openConnection();
// 設定連接引數
servletConnection.setRequestMethod("POST"); // 請求型別為post
servletConnection.setDoOutput(true); // 是否可讀
servletConnection.setDoInput(true); // 是否可寫
servletConnection.setAllowUserInteraction(true); // 是否可互動
return servletConnection;
}
獲取服務端反饋回來的結果
/**
* @desc 獲取服務端反饋回來的結果
* @param servletConnection
* @throws IOException
*/
public void getResponseResult(HttpURLConnection servletConnection)
throws IOException {
System.out.println("===============**服務端的回傳值**==================");
// 獲取回傳的資料
InputStream inputStream = servletConnection.getInputStream();//獲取反饋回來的流
//創建一個緩沖讀取的reader物件
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//創建一個能夠承接回傳來值得sb
StringBuffer sb = new StringBuffer();
//創建一個能夠臨時存盤讀取一行資訊的變數
String strMessage = "";
//開始回圈讀取回傳的流資訊
while ((strMessage = reader.readLine()) != null) {
sb.append(strMessage);//將回傳的流的資訊逐行的壓如到sb中
}
System.out.println("接識訓傳值:" + sb);
}
最后的呼叫方法
/**
* @throws IOException
* @desc 用于呼叫方法發送報文的方法
*/
public void sendMessage() throws IOException {
try {
System.out.println("=================開始發送報文=================");
// 建立連接
HttpURLConnection servletConnection = cerateServletUrl();
// 寫入資料
xmlWriteStream(servletConnection);
// 獲取回傳資料
getResponseResult(servletConnection);
} catch (java.net.ConnectException e) {
System.out.println("客戶端與服務端連接例外,請再次嘗試");
}
}
接收報文
服務端使用web專案進行構建
在service中設定編碼集
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
獲取客戶端發送過來的報文
//----------------通過request.getInputStream()獲取輸入的流----------------------
// 指定每次8kb
final int BUFFER_SIZE = 8 * 1024;
byte[] buffer = new byte[BUFFER_SIZE];
// 獲取輸出流,與客戶端的輸出流相對應
ServletInputStream sis = request.getInputStream();
// System.out.println("sis:"+sis);
int length = 0;
// 創建位元組輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
do {
length = sis.read(buffer);
if (length > 0) {
// 寫入至位元組輸出流
baos.write(buffer, 0, length);
}
} while (length * 2 == BUFFER_SIZE);
// 把位元組輸出流轉為字串,得到客戶端發送的資料,即為報文
String bodyData = new String(baos.toByteArray());
此時bodyData就是客戶端發送來的報文資料:
<?xml version="1.0" encoding="utf-8"?>
<request_data>
<request_token>BCDBCD</request_token>
<request_cardNum>62284801912705</request_cardNum>
<request_name>張飛</request_name>
<request_pass>123123</request_pass>
<request_time>2021年01月25日 14:51:52</request_time>
<monery_count>200.00</monery_count>
<shop_name>吉野家</shop_name>
<shop_id>JYJ</shop_id>
<sale_no>fc4c66dc-b54b-4052-89c1-902be7569f18</sale_no>
</request_data>
讀該xml可分析資料:張飛在2021年01月25日 14:51:52在商家id為JYJ的吉野家消費了200.00元,本次消費的流水單號為fc4c66dc-b54b-4052-89c1-902be7569f18,使用的卡號為62284801912705,該卡密碼為123123(未采用加密),且當前的標識碼為BCDBCD
決議報文
客戶端發送的報文資料為Xml型別,所以直接用Xml的資料決議方法決議即可
// 獲取報文之后,開始決議報文,即為決議Xml
//1.初始化jdk中的用來決議xml的dom工廠
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//2:獲得具體的dom決議器
DocumentBuilder db = dbf.newDocumentBuilder();
//3: 決議一個xml檔案,獲得Document物件(根結點)
InputSource is = new InputSource(new StringReader(bodyData));
Document document = null;
try{
document = db.parse(is);//將流轉換成document物件
}catch(Exception e){
return ;
}
獲取完document物件之后,開始決議
//通過抓取根節點進而獲取子節點
NodeList list = document.getElementsByTagName("request_data");
Map<String, Object> map = new HashMap<String, Object>();//將抓取之后獲得到的值存在map中
XmlServiceImpl service = new XmlServiceImpl();
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element) list.item(i);//通過item(i)獲取根節點下的每一個子節點
//1.識別碼
String request_token = element.getElementsByTagName("request_token").item(0).getFirstChild().getNodeValue();
map.put("request_token", request_token);
//2.卡號
String request_cardNum = element.getElementsByTagName("request_cardNum").item(0).getFirstChild().getNodeValue();
map.put("request_cardNum", request_cardNum);
//3.持卡人姓名
String request_name = element.getElementsByTagName("request_name").item(0).getFirstChild().getNodeValue();
map.put("request_name", request_name);
//4.該卡的密碼
String request_pass = element.getElementsByTagName("request_pass").item(0).getFirstChild().getNodeValue();
map.put("request_pass", request_pass);
//5.本次消費請求的時間
String request_time = element.getElementsByTagName("request_time").item(0).getFirstChild().getNodeValue();
map.put("request_time", request_time);
//6.本次消費的金額
String monery_count = element.getElementsByTagName("monery_count").item(0).getFirstChild().getNodeValue();
map.put("monery_count", monery_count);
//7.本次消費到的商家的名字
String shop_name = element.getElementsByTagName("shop_name").item(0).getFirstChild().getNodeValue();
map.put("shop_name", shop_name);
//8.本次消費到的商家的id
String shop_id = element.getElementsByTagName("shop_id").item(0).getFirstChild().getNodeValue();
map.put("shop_id", shop_id);
//9.本次消費到的流水單號
String sale_no = element.getElementsByTagName("sale_no").item(0).getFirstChild().getNodeValue();
map.put("sale_no", sale_no);
}
此時輸出map物件,查看資料
{request_name=張飛, shop_id=JYJ, request_time=2021年01月25日 14:51:52, request_token=BCDBCD, monery_count=200.00, sale_no=fc4c66dc-b54b-4052-89c1-902be7569f18, request_cardNum=62284801912705, shop_name=吉野家, request_pass=123123}
回傳報文
一切無誤后,回傳報文
// 要回傳的報文
StringBuffer resultBuffer = new StringBuffer();
resultBuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
resultBuffer.append("<request_data>");
resultBuffer.append("<request_name>"+request_name+"</request_name>");
resultBuffer.append("<request_cardNum>"+request_cardNum+"</request_cardNum>");
resultBuffer.append("<request_time>"+new Dates().CurrentYMDHSMTime()+"</request_time>");
resultBuffer.append("<shop_name>"+shop_name+"</shop_name>");
resultBuffer.append("<sale_no>"+sale_no+"</sale_no>");
resultBuffer.append("<request_token>成功了</request_token>");
resultBuffer.append("</request_data>");
// 設定發送報文的格式
response.setContentType("text/xml");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println(resultBuffer.toString());
out.flush();
out.close();
學習交流q群:470464545,大家一起學習進步,CSDN博客:lolly1023
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252720.html
標籤:其他
