JSon跨平台跨语言传输数据(持续更新中)

一、Java平台JSon数据传输。转自:java Socket 使用通用json包 发送 json对象java Socket 使用通用json包 发送 json对象

  在使用json进行socket进行通信中,由于服务器使用的json 和 客户端使用的json版本不同,因此改用通用的json包来通信。

  引入的包为 org.json,jar   可以通用,而且不必使用其他的一些需要引入的其他json依赖包,文章中的例子是将一张图片发送到服务器端,服务器端收到信息之后返回给客户端是否接受成功的信息 

  这里贴出客户端与服务器端的代码

 1 package service;  
 2 import java.io.ByteArrayOutputStream;  
 3 import java.io.DataInputStream;  
 4 import java.io.DataOutputStream;  
 5 import java.io.IOException;  
 6 import java.net.Socket;  
 7 import java.util.HashMap;  
 8 import java.util.Map;  
 9 import org.json.JSONArray;  
10 import org.json.JSONException;  
11 import org.json.JSONObject;  
12 import java.io.BufferedInputStream;  
13 import cn.edu.thu.cv.util.Base64Image;  
14   
15 public class Client {  
16     public static final String IP_ADDR = "***.***.***.***";//服务器地址  这里要改成服务器的ip  
17     public static final int PORT = 12345;//服务器端口号    
18       
19       
20     public static int register(String name,String imgPath,int opNum){  
21         String imgStr = Base64Image.GetImageStr(imgPath);//是将图片的信息转化为base64编码  
22         int isRegSuccess = 0;  
23          while (true) {    
24                 Socket socket = null;  
25                 try {  
26                     //创建一个流套接字并将其连接到指定主机上的指定端口号  
27                     socket = new Socket(IP_ADDR, PORT);    
28                     System.out.println("连接已经建立");          
29                     //向服务器端发送数据    
30                     Map<String, String> map = new HashMap<String, String>();  
31                     map.put("name",name);  
32                     map.put("img",imgStr);  
33                     map.put("op",opNum+"");  
34                     //将json转化为String类型    
35                     JSONObject json = new JSONObject(map);  
36                     String jsonString = "";  
37                         jsonString = json.toString();  
38                     //将String转化为byte[]  
39                     //byte[] jsonByte = new byte[jsonString.length()+1];  
40                     byte[] jsonByte = jsonString.getBytes();  
41                     DataOutputStream outputStream = null;  
42                     outputStream = new DataOutputStream(socket.getOutputStream());  
43                         System.out.println("发的数据长度为:"+jsonByte.length);  
44                     outputStream.write(jsonByte);  
45                     outputStream.flush();  
46                         System.out.println("传输数据完毕");  
47                         socket.shutdownOutput();  
48                       
49                     //读取服务器端数据    
50                     DataInputStream inputStream = null;  
51                     String strInputstream ="";  
52                     inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));   
53                     strInputstream=inputStream.readUTF();  
54                     System.out.println("输入信息为:"+strInputstream);  
55                     JSONObject js = new JSONObject(strInputstream);  
56                     System.out.println(js.get("isSuccess"));  
57                     isRegSuccess=Integer.parseInt((String) js.get("isSuccess"));   
58                     // 如接收到 "OK" 则断开连接    
59                     if (js != null) {    
60                         System.out.println("客户端将关闭连接");    
61                         Thread.sleep(500);    
62                         break;    
63                     }    
64                       
65                 } catch (Exception e) {  
66                     System.out.println("客户端异常:" + e.getMessage());   
67                     break;  
68                 } finally {  
69                     if (socket != null) {  
70                         try {  
71                             socket.close();  
72                         } catch (IOException e) {  
73                             socket = null;   
74                             System.out.println("客户端 finally 异常:" + e.getMessage());   
75                         }  
76                     }  
77                 }  
78             }  
79          return isRegSuccess;     
80     }  
81       
82     public static void main(String[] args) {    
83           register("gongyunfei","D:/test1.jpg",1);//第三个参数为操作类型 服务器能够知道你在进行什么操作  
84    }    
85 }   

  服务器端的代码:

  1 package service;  
  2 import java.net.ServerSocket;  
  3 import java.net.Socket;  
  4 import java.util.ArrayList;  
  5 import java.util.HashMap;  
  6 import java.util.Map;  
  7 import java.util.Date;  
  8 import java.text.SimpleDateFormat;  
  9 import java.io.BufferedOutputStream;  
 10 import java.io.ByteArrayOutputStream;  
 11 import java.io.DataInputStream;  
 12 import java.io.DataOutputStream;  
 13 import org.json.JSONArray;  
 14 import org.json.JSONException;  
 15 import org.json.JSONObject;  
 16 import cn.edu.thu.cv.util.Base64Image;  
 17   
 18   
 19 public class Server {  
 20     public static final int PORT = 12345;//监听的端口号     
 21           
 22     public static void main(String[] args) {    
 23         System.out.println("服务器启动...\n");    
 24       //  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);  
 25         Server server = new Server();    
 26         server.init();    
 27     }    
 28     
 29     public void init() {    
 30         try {    
 31             ServerSocket serverSocket = new ServerSocket(PORT);    
 32             while (true) {    
 33                 // 一旦有堵塞, 则表示服务器与客户端获得了连接    
 34                 Socket client = serverSocket.accept();    
 35                 // 处理这次连接    
 36                 new HandlerThread(client);    
 37             }    
 38         } catch (Exception e) {    
 39             System.out.println("服务器异常: " + e.getMessage());    
 40         }    
 41     }    
 42     
 43     private class HandlerThread implements Runnable {    
 44         private Socket socket;    
 45         public HandlerThread(Socket client) {    
 46             socket = client;    
 47             new Thread(this).start();    
 48         }    
 49     
 50         public void run() {    
 51                
 52             try {    
 53                 // 读取客户端数据    
 54                 System.out.println("客户端数据已经连接");  
 55                 DataInputStream inputStream = null;  
 56                 DataOutputStream outputStream = null;  
 57                 String strInputstream ="";           
 58                 inputStream =new DataInputStream(socket.getInputStream());                   
 59                 ByteArrayOutputStream baos = new ByteArrayOutputStream();  
 60                 byte[] by = new byte[2048];  
 61                 int n;  
 62                 while((n=inputStream.read(by))!=-1){  
 63                     baos.write(by,0,n);           
 64                 }  
 65                 strInputstream = new String(baos.toByteArray());  
 66 //                System.out.println("接受到的数据长度为:"+strInputstream);  
 67                 socket.shutdownInput();  
 68 //                inputStream.close();  
 69                 baos.close();  
 70                   
 71                   
 72                 // 处理客户端数据    
 73                 //将socket接受到的数据还原为JSONObject  
 74                 JSONObject json = new JSONObject(strInputstream);         
 75                 int op =Integer.parseInt((String)json.get("op"));    
 76                 System.out.println(op);  
 77                 switch(op){  
 78                   
 79                 //op为1 表示收到的客户端的数据为注册信息     op为2表示收到客户端的数据为检索信息       
 80                   
 81                 //当用户进行的操作是注册时  
 82                 case 1: String imgStr = json.getString("img");  
 83                         String name   = json.getString("name");  
 84                        //isSuccess 表示是否注册成功  
 85                         String isSuccess="1";  
 86                        // System.out.println("imgStr:"+imgStr);  
 87                         //用系统时间作为生成图片的名字   格式为yyyy-MM-dd-HH-mm-ss  
 88                         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");  
 89                         String imgName = df.format(new Date());  
 90                         Base64Image.GenerateImage(imgStr,"D:\\fromjia\\imageDB\\primary\\"+imgName+".jpg");  
 91                         //do something to process this image                        
 92                         //if success, return set isSuccess "1"  
 93                         //else set "0"    
 94                         System.out.println(name);                   
 95                         System.out.println("服务器接受数据完毕");  
 96                           
 97                         // 向客户端回复信息  --json对象//to be continued;  
 98                         Map<String, String> map = new HashMap<String, String>();  
 99                         map.put("isSuccess", isSuccess);  
100                         json = new JSONObject(map);  
101                     String jsonString = json.toString();                        
102                     outputStream = new DataOutputStream(new BufferedOutputStream (socket.getOutputStream()));     
103                     outputStream.writeUTF(jsonString);  
104                     outputStream.flush();  
105                     outputStream.close();  
106                     System.out.println("注册完成");  
107                         break;                                                                                         
108                 }   
109                   
110                 outputStream.close();  
111             } catch (Exception e) {    
112                 System.out.println("服务器 run 异常: " + e.getMessage());    
113             } finally {    
114                 if (socket != null) {    
115                     try {    
116                         socket.close();    
117                     } catch (Exception e) {    
118                         socket = null;    
119                         System.out.println("服务端 finally 异常:" + e.getMessage());    
120                     }    
121                 }    
122             }   
123         }    
124     }    
125 }  

  文中所要引用的import cn.edu.thu.cv.util.Base64Image代码为:

 1 package cn.edu.thu.cv.util;  
 2   
 3 import java.io.FileInputStream;  
 4 import java.io.FileOutputStream;  
 5 import java.io.IOException;  
 6 import java.io.InputStream;  
 7 import java.io.OutputStream;  
 8   
 9 import sun.misc.BASE64Decoder;  
10 import sun.misc.BASE64Encoder;  
11   
12 public class Base64Image   
13 {  
14     public static String GetImageStr(String imapath)  
15     {//将图片文件转化为字节数组字符串,并对其进行Base64编码处理  
16         InputStream in = null;  
17         byte[] data = null;  
18         //读取图片字节数组  
19         try   
20         {  
21             in = new FileInputStream(imapath);          
22             data = new byte[in.available()];  
23             in.read(data);  
24             in.close();  
25         }   
26         catch (IOException e)   
27         {  
28             e.printStackTrace();  
29         }  
30         //对字节数组Base64编码  
31         BASE64Encoder encoder = new BASE64Encoder();  
32         return encoder.encode(data);//返回Base64编码过的字节数组字符串  
33     }  
34     public static boolean GenerateImage(String imgStr, String output)  
35     {//对字节数组字符串进行Base64解码并生成图片  
36         if (imgStr == null) //图像数据为空  
37             return false;  
38         BASE64Decoder decoder = new BASE64Decoder();  
39         try   
40         {  
41             //Base64解码  
42             byte[] b = decoder.decodeBuffer(imgStr);  
43             for(int i=0;i<b.length;++i)  
44             {  
45                 if(b[i]<0)  
46                 {//调整异常数据  
47                     b[i]+=256;  
48                 }  
49             }  
50             //生成jpeg图片  
51             OutputStream out = new FileOutputStream(output);      
52             out.write(b);  
53             out.flush();  
54             out.close();  
55             return true;  
56         }   
57         catch (Exception e)   
58         {  
59             return false;  
60         }  
61     }  
62 }  

  之前认为写的时候还是很简单的,不过写的过程中遇到了一些问题,将这些问题总结一下如下:

1.传输文件过程中,要将文件转换成base64编码。

2.要统一好编程的工具、配置环境,包括使用的具体包的形式,我这次遇到的情况是:甲写服务器端,使用的是json2.4的包,并且测试没有问题。乙写的客户端引用了一个j2E,里面包含了json2.1,而且json2.1无法删除替换,这样通信方式就会改变,服务器与客户端无法完成通信。只能使用通用json包,增加了不少工作量。

3.在使用org.json 中,传输比较小的字符串,可以使用outputStream.writeUTF(String);这个函数来写,但是当传输比较大的文件的时候就必须将String转化为byte[]来进行传输,不然会报出异常说是编码太大无法传输。

4.在发送完数据之后要记得flush();

5.在使用outputStream.close();或者inputStream.close();来关闭服务器的输入流和输出流的过程中,socket也会同时关闭,如果想只关闭输入流或者输出流而不关闭socket就可以使用socket.shutdownInput();

 

二、VB6平台JSon数据传输,参考Java解析(读取)Json数据

 

  【Function 1.】vb6里不支持json对象,这里使用通过引用js来实现json的解析获取简单的json串里的值

1 'JSon解析接口:JSONPath为string中能标志出字段的标识,JSONString为原始串
2 Public Function JSONParse(ByVal JSONPath As String, ByVal JSONString As String) As Variant 
3 Dim JSON As Object 
4 Set JSON = CreateObject("MSScriptControl.ScriptControl") 
5 JSON.Language = "JScript" 
6 JSONParse = JSON.eval("JSON=" & JSONString & ";JSON." & JSONPath & ";") 
7 Set JSON = Nothing 
8 End Function

  调用方式:JSONPath为数据访问路径JSONString为JSON格式源数据,如源数据内容调用:

1 '1、直接取值
2 ecode=Json("ecode", JsonString)
3 
4 '2、数组长度获取
5 pkgCount=Json("pkg.length", JsonString)
6 
7 '3、数组内取值
8 cName=Json("pkg[0].name",JsonString)

  【Function 2】通过类似模板的方式解析

 1 Private Sub Command1_Click()
 2     Dim ScriptControl As Object, Psw As Object, JscriptCode$
 3     JscriptCode = "function toObject(json) {eval(""var o=""+json);return o;}"
 4     Set ScriptControl = CreateObject("MSScriptControl.ScriptControl")
 5     With ScriptControl
 6         .Language = "Javascript"
 7         .Timeout = -1
 8         .AddCode JscriptCode
 9         Set Psw = .Run("toObject", Text1.Text)
10     End With
11     MsgBox "province:" & Psw.result.province '& vbCrLf & "day1:" & Psw.result.birthday.day1 & vbCrLf & "city:" & Psw.result.city
12     MsgBox "province:" & Psw.result.country
13     MsgBox "province:" & Psw.result.nick
14 End Sub

  测试json序列:

 1 {
 2     "retcode":0,
 3     "result":{
 4         "face":201,
 5         "birthday":    {
 6             "month":10,
 7             "year":1899,
 8             "day":13
 9                 },
10         "occupation":"",
11         "phone":"",
12         "allow":1,
13         "college":"",
14         "uin":57610310,
15         "constel":9,
16         "blood":1,
17         "homepage":"",
18         "stat":10,
19         "vip_info":0,
20         "country":"中国",
21         "city":"宁波",
22         "personal":"\r\n",
23         "nick":"57610310",
24         "shengxiao":5,
25         "email":"",
26         "client_type":41,
27         "province":"浙江",
28         "gender":"male","mobile":""
29         }
30 }   
1 Dim ScriptObj As Object
2 Dim JsonStr As String
3 JsonStr = "{""code"":""0"",""msg"":""SUCCESS""}"
4 
5 Set ScriptObj = CreateObject("MSScriptControl.ScriptControl")
6 ScriptObj.Language = "JavaScript"
7 ScriptObj.AddCode "var Json = " & JsonStr & ";"
8 
9 MsgBox ScriptObj.eval("Json.code")

  遍历json键值对较多的复杂json串,但是这种方法性能较差,适用场景有限

 1 Dim ScriptObj As Object
 2 Dim JsonStr, sourceData As String
 3 JsonStr = "{""code"":""0"",""msg"":""SUCCESS"",""data": _
 4 {""AAA"":""111"",""BBB"",""222"",""CCC"",""333"",……}"}"
 5 
 6 Set ScriptObj = CreateObject("MSScriptControl.ScriptControl")
 7 ScriptObj.Language = "JavaScript"
 8 ScriptObj.AddCode "var Json = " & JsonStr & ";var result = """";"
 9 
10 '执行js语句,遍历json对象,可嵌套循环
11 ScriptObj.ExecuteStatement ("for (var key in Json.data) {result += ""|"" + key + "":"" + Json.data[key];}") 
12 
13 sourceData = ScriptObj.eval("lockinfo")
14 
15 Dim arrStr() As String
16 Dim temStr As Variant
17 
18 arrStr = Split(sourceData, "|")'解析拼接的字符串
19 For Each temStr In arrStr
20     If temStr <> Empty Then
21         msgbox Split(temStr, ":")(0) & ":" & Split(temStr, ":")(1)
22     End If
23 Next
posted @ 2019-08-28 23:50  傍风无意  阅读(1038)  评论(0)    收藏  举报