報文(message)是網絡中交換與傳輸的數據單元,即站點一次性要發送的數據塊。報文包含了將要發送的完整的數據信息,其長短很不一致,長度不限且可變。
個人理解:從客戶端把字符串寫入字節數組流中傳達至服務端,但是此字符串是XML格式的,然后到了服務端,使用字節數組進行獲取該字符串,再獲取該字符串的document對象(因為字符串是xml格式的),然后解析獲取數據即可。
發送報文
先創建生成報文的方法,添加了xml數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/** * @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轉為流寫入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/** * @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(); // 關閉流 } |
創建客戶端與服務端的連接并且設置發送報文的一些屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/** * @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; } |
獲取服務端反饋回來的結果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/** * @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); } |
最后的調用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/** * @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中設置編碼集
1
2
|
request.setCharacterEncoding( "utf-8" ); response.setCharacterEncoding( "utf-8" ); |
獲取客戶端發送過來的報文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//----------------通過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
就是客戶端發送來的報文數據:
1
2
3
4
5
6
7
8
9
10
11
12
|
<?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的數據解析方法解析即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 獲取報文之后,開始解析報文,即為解析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對象之后,開始解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
//通過抓取根節點進而獲取子節點 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對象,查看數據
1
|
{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 } |
返回報文
一切無誤后,返回報文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 要返回的報文 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(); |
到此這篇關于Java發送報文與接收報文的文章就介紹到這了,更多相關Java發送報文與接收報文內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/lolly1023/article/details/113112403