网络通讯数据.传输json(java<==>C#)
ZC:主要是测试解决 时间转成JSON不一样的问题
ZC:java中转换时间格式的关键是“JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[]{ strDatetimeFormat }));”
ZC:C#中转换时间格式的关键是“IsoDateTimeConverter timeConverter = new IsoDateTimeConverter(); timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";”
1、java
导入 第三方:
1.1、TestJson.java
package shh.Main; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Date; import net.sf.ezmorph.object.DateMorpher; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; import net.sf.json.util.JSONUtils; import shh.GlobalParam.GlobalParam; import shh.entity.communicate.JsonDateValueProcessor; import shh.entity.db.RealTimeCoalFlowWidth; // java中json的使用和解析 - Java_Panda - 博客园.html “https://www.cnblogs.com/LearnAndGet/p/10009646.html” // JSON数据转换之net.sf.json包的使用 - 娜娜娜娜小姐姐 - 博客园.html “https://www.cnblogs.com/nananana/p/9263708.html” public class TestJson { public static void main(String[] args) throws Exception { String strDatetimeFormat = "yyyy-MM-dd HH:mm:ss.SSS"; // ZC: 用于 java object --> json JsonConfig jsonConfig = new JsonConfig(); jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor(strDatetimeFormat));
// ZC: 测试下来 下面你的这个是关键!! 上面的 jsonConfig 用不用都无所谓... // ZC: 用于 json --> java object JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[]{ strDatetimeFormat })); // *** System.out.println(""); long l01 = System.currentTimeMillis(); java.util.Date pp = new Timestamp(l01); System.out.println("pp : " + pp); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); RealTimeCoalFlowWidth cfw = new RealTimeCoalFlowWidth(); cfw.setCameraID(1); cfw.setCoalFlowDateTime(new Timestamp(l01)); cfw.setCoalFlowWidth((short)3); cfw.setCoalFlowSectionArea((short)4); cfw.setCoalFlowVelocity((short)5); RealTimeCoalFlowWidth cfw1 = new RealTimeCoalFlowWidth(); cfw1.setCameraID(2); cfw1.setCoalFlowDateTime(new Timestamp(l01-100)); cfw1.setCoalFlowWidth((short)30); cfw1.setCoalFlowSectionArea((short)40); cfw1.setCoalFlowVelocity((short)50); RealTimeCoalFlowWidth[] cfws = {cfw, cfw1}; JSONArray jarr = JSONArray.fromObject(cfws, jsonConfig); System.out.println(jarr); // *** JSONArray jarr1 = JSONArray.fromObject(jarr.toString()); RealTimeCoalFlowWidth[] ttt = (RealTimeCoalFlowWidth[])JSONArray.toArray(jarr1, RealTimeCoalFlowWidth.class); System.out.println("ttt.length :" + ttt.length); for (int i=0; i<ttt.length; i++) { RealTimeCoalFlowWidth t = ttt[i]; System.out.println("["+i+"] :" + t.getCameraID()+", "+sdf.format(t.getCoalFlowDateTime())+", " +t.getCoalFlowWidth()+", "+t.getCoalFlowSectionArea()+", "+t.getCoalFlowVelocity()); // System.out.println("["+i+"] :" + t.getCameraID()+", "+(t.getCoalFlowDateTime())+", " // +t.getCoalFlowWidth()+", "+t.getCoalFlowSectionArea()+", "+t.getCoalFlowVelocity()); } //Json_CoalFlowWidth(); } // 分析结果数据(DB:煤流宽度表) public static void Json_CoalFlowWidth() throws IOException { System.out.println(""); long l01 = System.currentTimeMillis(); java.util.Date pp = new Timestamp(l01); System.out.println("pp : " + pp); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); System.out.println("sdf.format(pp) : " + sdf.format(pp)); System.out.println("sdf.format(pp) : " + sdf.format(new Timestamp(l01-100))); RealTimeCoalFlowWidth cfw = new RealTimeCoalFlowWidth(); cfw.setCameraID(1); cfw.setCoalFlowDateTime(new Timestamp(l01)); cfw.setCoalFlowWidth((short)3); cfw.setCoalFlowSectionArea((short)4); cfw.setCoalFlowVelocity((short)5); RealTimeCoalFlowWidth cfw1 = new RealTimeCoalFlowWidth(); cfw1.setCameraID(2); cfw1.setCoalFlowDateTime(new Timestamp(l01-100)); cfw1.setCoalFlowWidth((short)30); cfw1.setCoalFlowSectionArea((short)40); cfw1.setCoalFlowVelocity((short)50); GlobalParam.JsonConfig1.setRootClass(RealTimeCoalFlowWidth.class); RealTimeCoalFlowWidth[] cfws = {cfw, cfw1}; JSONArray jarr = JSONArray.fromObject(cfws, GlobalParam.JsonConfig1); System.out.println(jarr); RealTimeCoalFlowWidth[] ttt = (RealTimeCoalFlowWidth[])JSONArray.toArray(jarr, RealTimeCoalFlowWidth.class); System.out.println("ttt.length :" + ttt.length); for (int i=0; i<ttt.length; i++) { RealTimeCoalFlowWidth t = ttt[i]; System.out.println("["+i+"] :" + t.getCameraID()+", "+sdf.format(t.getCoalFlowDateTime())+", " +t.getCoalFlowWidth()+", "+t.getCoalFlowSectionArea()+", "+t.getCoalFlowVelocity()); //System.out.println(t.getCoalFlowDateTime()); } } }
1.2、RealTimeCoalFlowWidth.java
package shh.entity.db; import java.io.Serializable; // sqlserver数据库类型对应Java中的数据类型 - _萨瓦迪卡 - 博客园.html(https://www.cnblogs.com/cunkouzh/p/5504052.html) // ZC: Timestamp没有默认构造函数,无法反射... import java.util.Date; public class RealTimeCoalFlowWidth { int CameraID; //Timestamp CoalFlowDateTime; Date CoalFlowDateTime; short CoalFlowWidth; short CoalFlowSectionArea; short CoalFlowVelocity; public int getCameraID() { return CameraID; } public void setCameraID(int cameraID) { CameraID = cameraID; } // public Timestamp getCoalFlowDateTime() { // return CoalFlowDateTime; // } // public void setCoalFlowDateTime(Timestamp coalFlowDateTime) { // CoalFlowDateTime = coalFlowDateTime; // } public Date getCoalFlowDateTime() { return CoalFlowDateTime; } public void setCoalFlowDateTime(Date coalFlowDateTime) { CoalFlowDateTime = coalFlowDateTime; } public short getCoalFlowWidth() { return CoalFlowWidth; } public void setCoalFlowWidth(short coalFlowWidth) { CoalFlowWidth = coalFlowWidth; } public short getCoalFlowSectionArea() { return CoalFlowSectionArea; } public void setCoalFlowSectionArea(short coalFlowSectionArea) { CoalFlowSectionArea = coalFlowSectionArea; } public short getCoalFlowVelocity() { return CoalFlowVelocity; } public void setCoalFlowVelocity(short coalFlowVelocity) { CoalFlowVelocity = coalFlowVelocity; } }
1.3、JsonDateValueProcessor.java
package shh.entity.communicate; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import net.sf.ezmorph.object.DateMorpher; import net.sf.json.JsonConfig; import net.sf.json.processors.JsonValueProcessor; import net.sf.json.util.JSONUtils; // net.sf.json 时间格式的转化 - LinVan - 博客园.html(https://www.cnblogs.com/linvan/p/5979820.html) public class JsonDateValueProcessor implements JsonValueProcessor { private String format = "";//"yyyy-MM-dd HH:mm:ss"; public JsonDateValueProcessor() { super(); } public JsonDateValueProcessor(String format) { super(); this.format = format; } @Override public Object processArrayValue(Object paramObject, JsonConfig paramJsonConfig) { // System.out.println("<-- <-- <-- <-- <-- <-- <-- <-- <-- "); return process(paramObject); } @Override public Object processObjectValue(String paramString, Object paramObject, JsonConfig paramJsonConfig) { // System.out.println("--> --> --> --> --> --> --> --> --> "+paramString); return process(paramObject); } private Object process(Object value) { if (value instanceof Date) { // System.out.println("<== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== "); //SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA); SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(value); } return value == null ? "" : value.toString(); } public static JsonConfig JsonConfig_Z() { JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd HH:mm:ss.SSS"})); JsonConfig jsonConfig = new JsonConfig(); jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss.SSS")); return jsonConfig; } }
2、C#
引入:
2.1、
private void Click_JsonTest(object sender, RoutedEventArgs e) { IsoDateTimeConverter timeConverter = new IsoDateTimeConverter(); timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; // *** DateTime dt = DateTime.Now; RealTimeCoalFlowWidth cfw = new RealTimeCoalFlowWidth(); cfw.CameraID = 1; //Timestamp CoalFlowDateTime; cfw.CoalFlowDateTime = dt; cfw.CoalFlowWidth1 = 3; cfw.CoalFlowSectionArea = 4; cfw.CoalFlowVelocity = 5; dt.AddDays(-1); RealTimeCoalFlowWidth cfw1 = new RealTimeCoalFlowWidth(); cfw1.CameraID = 10; //Timestamp CoalFlowDateTime; cfw1.CoalFlowDateTime = dt.AddSeconds(-3); cfw1.CoalFlowWidth1 = 30; cfw1.CoalFlowSectionArea = 40; cfw1.CoalFlowVelocity = 50; RealTimeCoalFlowWidth[] cfws = { cfw, cfw1 }; string str = JsonConvert.SerializeObject(cfws, timeConverter); Console.WriteLine(str); RealTimeCoalFlowWidth[] cfws1 = JsonConvert.DeserializeObject<RealTimeCoalFlowWidth[]>(str, timeConverter); Console.WriteLine("cfws1 : "); Console.WriteLine("\t" + cfws1[0].CameraID); Console.WriteLine("\t" + cfws1[0].CoalFlowDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")); Console.WriteLine("\t" + cfws1[0].CoalFlowWidth1); Console.WriteLine("\t" + cfws1[0].CoalFlowSectionArea); Console.WriteLine("\t" + cfws1[0].CoalFlowVelocity); Console.WriteLine(); Console.WriteLine("\t" + cfws1[1].CameraID); Console.WriteLine("\t" + cfws1[1].CoalFlowDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")); Console.WriteLine("\t" + cfws1[1].CoalFlowWidth1); Console.WriteLine("\t" + cfws1[1].CoalFlowSectionArea); Console.WriteLine("\t" + cfws1[1].CoalFlowVelocity); // *** //DateTime dt = DateTime.Now; //string str = JsonConvert.SerializeObject(dt, GlobalParam.IsoDateTimeConverter1); //Console.WriteLine(str); ////string s = @"2019-12-17T12:45:07.8048002+08:00"; //string s = "\"2019-12-17 12:45:07.888\""; //DateTime dt1 = JsonConvert.DeserializeObject<DateTime>(s, GlobalParam.IsoDateTimeConverter1); ////DateTime dt1 = JsonConvert.DeserializeObject<DateTime>(str, timeConverter); //Console.WriteLine(dt1.ToString("yyyy-MM-dd HH:mm:ss.fff")); }
2.2、
public class RealTimeCoalFlowWidth { public int CameraID; //Timestamp CoalFlowDateTime; public DateTime CoalFlowDateTime; public short CoalFlowWidth1; public short CoalFlowSectionArea; public short CoalFlowVelocity; }
2.3、经测试,C#中 list转json 和 数组转json 生成的结果是一样的:
RealTimeCoalFlowWidth[] cfws = { cfw, cfw1 };
// 下面是 数组转json的结果 // [{"CameraID":1,"CoalFlowDateTime":"2019-12-24 08:31:50.879","CoalFlowWidth1":3,"CoalFlowSectionArea":4,"CoalFlowVelocity":5},{"CameraID":10,"CoalFlowDateTime":"2019-12-24 08:31:47.879","CoalFlowWidth1":30,"CoalFlowSectionArea":40,"CoalFlowVelocity":50}] //List<RealTimeCoalFlowWidth> cfws = new List<RealTimeCoalFlowWidth>(); //cfws.Add(cfw); //cfws.Add(cfw1);
// 下面是 List转json的结果 // [{"CameraID":1,"CoalFlowDateTime":"2019-12-24 08:31:23.328","CoalFlowWidth1":3,"CoalFlowSectionArea":4,"CoalFlowVelocity":5},{"CameraID":10,"CoalFlowDateTime":"2019-12-24 08:31:20.328","CoalFlowWidth1":30,"CoalFlowSectionArea":40,"CoalFlowVelocity":50}] string str = JsonConvert.SerializeObject(cfws, timeConverter); Console.WriteLine(str);
2.4、测试:
string str = "{ \"CameraID\":\"1\",\"CoalFlowDateTime\":\"2019-12-24 08:31:50.879\",\"CoalFlowWidth1\":\"3\",\"CoalFlowSectionArea\":4,\"CoalFlowVelocity\":5}"; RealTimeCoalFlowWidth cfw = JsonConvert.DeserializeObject<RealTimeCoalFlowWidth>(str, timeConverter); Console.WriteLine("\t" + cfw.CameraID); Console.WriteLine("\t" + cfw.CoalFlowDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")); Console.WriteLine("\t" + cfw.CoalFlowWidth1); Console.WriteLine("\t" + cfw.CoalFlowSectionArea); Console.WriteLine("\t" + cfw.CoalFlowVelocity);
输出:(这里测试,C#里面的 int型、short型 可以从 json的string型里面正确的转换得到,于是 java的服务端代码,可以无脑的将SQL查到的数据都转成string了 [未测试 时间上的转换能否OK...])
1 2019-12-24 08:31:50.879 3 4 5
2.5、测试发现,Newtonsoft.Json 在执行 序列化操作时,无法指定是 序列化 子类还是基类。要想 只序列化 一个对象实例的基类部分属性的话,貌似 我没找到如何做...(反序列化 貌似倒是 可以指定使用具体哪种类型进行反序列化操作的...)
PS:我发现,需要 序列化的对象,如果 属性中 有代理(delegate)的话,序列化 操作会报错 ! ! !
现在想到一个 折中的方式:通过反射 创建基类实例X,然后 将子类中相关的属性赋值给 实例X,然后对 实例X 进行序列化,最后释放 实例X。
测试代码:
(1)、子类+基类:
class Base { public int Base1 { get; set; } public int Base2 { get; set; } public virtual string SerializeSHH(Type baseType) { Type childType = this.GetType(); object baseObj = Activator.CreateInstance(baseType); PropertyInfo[] basePI = baseType.GetProperties(); for (int i = 0; i < basePI.Length; i++) { PropertyInfo childPI = childType.GetProperty(basePI[i].Name); if (childPI != null) basePI[i].SetValue(baseObj, childPI.GetValue(this)); } string rst = JsonConvert.SerializeObject(baseObj); baseObj = null; return rst; //return null; } } class Child1 : Base { public int C1 { get; set; } }
(2)、序列化代码
Child1 c1 = new Child1(); Console.WriteLine(((Base)c1).SerializeSHH(typeof(Base))); Console.WriteLine(((Base)c1).SerializeSHH(typeof(Child1)));
(3)、控制台输出
{"Base1":0,"Base2":0} {"Base1":0,"Base2":0,"C1":0}
3、
4、
5、