GSON解析json中存在不确定实体类

来源:互联网 发布:南方s730网络设置 编辑:程序博客网 时间:2024/05/16 12:01

这几天遇到个解析json的问题,返回的json数据中包含不同的实体类,实体类的键值是确定的但是类型是不确定的。(尴尬描述可能不对,下面给出json例子)

json数据例子如下:
String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";
String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";
String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,:world!', cc:true}}";

网上找了很久,首先找到定义d为泛型,然后用JSONObject  jsond = new JSONObject(String arg0)的方法得到d的json数据,最后用D d =  gson.fromJson( jsond.toString(), D.class)解析出具体的实体类。下面看一下具体的实现。

Entity.java

public class Entity {private int a;private String b;private boolean c;private Object d;public int getA() {return a;}public void setA(int a) {this.a = a;}public String getB() {return b;}public void setB(String b) {this.b = b;}public boolean isC() {return c;}public void setC(boolean c) {this.c = c;}public Object getD() {return d;}public void setD(Object d) {this.d = d;}@Overridepublic String toString() {return "Entity [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";}}
DA.java

public class DA {private int aa;public int getAa() {return aa;}public void setAa(int aa) {this.aa = aa;}@Overridepublic String toString() {return "DA [aa=" + aa + "]";}}

DB.java

public class DB {private int ba;private String bb;public int getBa() {return ba;}public void setBa(int ba) {this.ba = ba;}public String getBb() {return bb;}public void setBb(String bb) {this.bb = bb;}@Overridepublic String toString() {return "DB [ba=" + ba + ", bb=" + bb + "]";}}

DC.java

public class DC {private int ca;private String cb;private boolean cc;public DC(int ca, String cb, boolean cc) {super();this.ca = ca;this.cb = cb;this.cc = cc;}public int getCa() {return ca;}public void setCa(int ca) {this.ca = ca;}public String getCb() {return cb;}public void setCb(String cb) {this.cb = cb;}public boolean isCc() {return cc;}public void setCc(boolean cc) {this.cc = cc;}@Overridepublic String toString() {return "DC [ca=" + ca + ", cb=" + cb + ", cc=" + cc + "]";}}
jsontest.java

import com.google.gson.Gson;import com.mathworks.toolbox.javabuilder.external.org.json.JSONObject;public class jsontest {public static void main(String[] args) {String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,:world!', cc:true}}";    Gson gson = new Gson();      Entity ea = gson.fromJson(dataA, Entity.class);    Entity eb = gson.fromJson(dataB, Entity.class);    Entity ec = gson.fromJson(dataC, Entity.class);    System.out.println("ea ="+ea.toString());    System.out.println("eb ="+eb.toString());    System.out.println("ec ="+ec.toString());    ea = gson.fromJson(dataA, Entity.class);    eb = gson.fromJson(dataB, Entity.class);    ec = gson.fromJson(dataC, Entity.class);    if(ea.getA()==1){    System.out.println("ea.getD() ="+ea.getD().toString());    try {JSONObject d = new JSONObject(ea.getD().toString());    System.out.println("d ="+d.toString());    DA da =  gson.fromJson(d.toString(), DA.class);    System.out.println("da ="+da.toString());} catch (Exception e) {e.printStackTrace();}    }    System.out.println("");    if(eb.getA()==2){    System.out.println("eb.getD() ="+eb.getD().toString());    try {JSONObject d = new JSONObject(eb.getD().toString());    System.out.println("d ="+d.toString());    DB db =  gson.fromJson(d.toString(), DB.class);    System.out.println("db ="+db.toString());} catch (Exception e) {e.printStackTrace();}    }    System.out.println("");    if(ec.getA()==3){    System.out.println("ec.getD() ="+ec.getD().toString());    try {JSONObject d = new JSONObject(ec.getD().toString());    System.out.println("d ="+d.toString());    DC dc =  gson.fromJson(d.toString(), DC.class);    System.out.println("dc ="+dc.toString());} catch (Exception e) {e.printStackTrace();}    }}}
运行结果:

ea =Entity [a=1, b=Hello,world!, c=true, d={aa=1.0}]eb =Entity [a=2, b=Hello,world!, c=true, d={ba=1.0, bb=Hello word!}]ec =Entity [a=3, b=Hello,world!, c=true, d={ca=1.0, cb=Hello,:world!, cc=true}]ea.getD() ={aa=1.0}d ={"aa":1}da =DA [aa=1]eb.getD() ={ba=1.0, bb=Hello word!}d ={"bb":"Hello word!","ba":1}db =DB [ba=1, bb=Hello word!]ec.getD() ={ca=1.0, cb=Hello,:world!, cc=true}com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Missing value at character 18 of {ca=1.0, cb=Hello,:world!, cc=true}at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.nextValue(JSONTokener.java:349)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:191)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)at com.example.json.jsontest.main(jsontest.java:51)


当字符串中包含,:等特殊符号时不能正确解析。原因是形如{ca=1.0, cb=Hello,:world!, cc=true}的字符串不能转换为json数据。

当dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,world!', cc:true}}";
报错
com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Expected a ':' after a key at character 25 of {ca=1.0, cb=Hello,world!, cc=true}at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:204)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)at com.example.json.jsontest.main(jsontest.java:51)

当dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello:world!', cc:true}}";报错com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Expected a ',' or '}' at character 18 of {ca=1.0, cb=Hello:world!, cc=true}at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:223)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)at com.example.json.jsontest.main(jsontest.java:51)
当dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,:world!', cc:true}}";报错com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Missing value at character 18 of {ca=1.0, cb=Hello,:world!, cc=true}at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.nextValue(JSONTokener.java:349)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:191)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)at com.example.json.jsontest.main(jsontest.java:51)
如果收到的json数据是dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:\'\"Hello,world!\"\', cc:true}}";则可以解析,因为第一次解析得到的是{ca=1.0, cb="Hello,world!", cc=true},可以转换成json数据,但是别人不可能按我的需求这样发给我。可怜

然后在网上继续找字符串转换为实体类,发现很多人说啥反射工厂模式,觉得意思就和编译原理里的词法分析、语法分析差不多,就是一个一个地进行匹配,然后我就像下面这样做。

jsonsubtest.java

import com.google.gson.Gson;public class jsonsubtest {public static void main(String[] args) {String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,world!', cc:true}}";    Gson gson = new Gson();      DC dctest = new DC(1, null, false);    String jsondctest = gson.toJson(dctest, DC.class);    System.out.println("jsondctest ="+jsondctest);        Entity ea = gson.fromJson(dataA, Entity.class);    Entity eb = gson.fromJson(dataB, Entity.class);    Entity ec = gson.fromJson(dataC, Entity.class);    System.out.println("ea ="+ea.toString());    System.out.println("eb ="+eb.toString());    System.out.println("ec ="+ec.toString());    DC dc1 = getD(ec.getD().toString());    System.out.println("dc1 ="+dc1.toString());    DC dc2 = getD("{ca=1.0, cc=true}");    System.out.println("dc2 ="+dc2.toString());    DC dc3 = getD("{ca=1.0, cb=Hello,cc=world!, cc=true}");    System.out.println("dc3 ="+dc3.toString());    DC dc4 = getDcut("{ca=1.0, cb=Hello,cc=world!, cc=true}");    System.out.println("dc4 ="+dc4.toString());    DC dc5 = getDcut("{ca=1.0, cb=Hello, cc=world!, cc=true}");    System.out.println("dc5 ="+dc5.toString());}public static DC getD(String srcstr) {//{ca=1.0, cb=Hello,world!, cc=true} {ca=1.0, cc=true}int a = 0;String b = null;boolean c = false;String temp = "";int start,end = 0;start = srcstr.indexOf("ca=");if(start!=-1){temp = srcstr.substring(start);end = temp.indexOf(", ");if(end!=-1)a = (int) Float.parseFloat(temp.substring(3, end));}start = srcstr.indexOf("cb=");if(start!=-1){temp = srcstr.substring(start);end = temp.indexOf(", cc");if(end!=-1)b = temp.substring(3, end);}start = srcstr.indexOf("cc=");if(start!=-1){temp = srcstr.substring(start);end = temp.indexOf("}");if(end!=-1)c = Boolean.parseBoolean(temp.substring(3, end));}DC dc = new DC(a, b, c);return dc;}private static DC getDcut(String srcstr) {int a = 0;String b = null;boolean c = false;String temp = "";int start,end = 0;    System.out.println("srcstr1 ="+srcstr);start = srcstr.indexOf("ca=");if(start!=-1){temp = srcstr.substring(start);end = temp.indexOf(", ");if(end!=-1)a = (int) Float.parseFloat(temp.substring(3, end));}if(start!=-1 && end!=-1){temp = srcstr.substring(start, end+2);srcstr = srcstr.replace(temp, "");}    System.out.println("srcstr2 ="+srcstr);start = srcstr.indexOf("cb=");if(start!=-1){temp = srcstr.substring(start);end = temp.indexOf(", cc");if(end!=-1)b = temp.substring(3, end);}if(start!=-1 && end!=-1){temp = srcstr.substring(start, end+4);srcstr = srcstr.replace(temp, "");}    System.out.println("srcstr3 ="+srcstr);start = srcstr.indexOf("cc=");if(start!=-1){temp = srcstr.substring(start);end = temp.indexOf("}");if(end!=-1)c = Boolean.parseBoolean(temp.substring(3, end));}DC dc = new DC(a, b, c);return dc;}}
运行结果:

jsondctest ={"ca":1,"cc":false}ea =Entity [a=1, b=Hello,world!, c=true, d={aa=1.0}]eb =Entity [a=2, b=Hello,world!, c=true, d={ba=1.0, bb=Hello word!}]ec =Entity [a=3, b=Hello,world!, c=true, d={ca=1.0, cb=Hello,world!, cc=true}]dc1 =DC [ca=1, cb=Hello,world!, cc=true]dc2 =DC [ca=1, cb=null, cc=true]dc3 =DC [ca=1, cb=Hello,cc=world!, cc=false]srcstr1 ={ca=1.0, cb=Hello,cc=world!, cc=true}srcstr2 ={ cb=Hello,cc=world!, cc=true}srcstr3 ={ cc=true}dc4 =DC [ca=1, cb=Hello,cc=world!, cc=true]srcstr1 ={ca=1.0, cb=Hello, cc=world!, cc=true}srcstr2 ={ cb=Hello, cc=world!, cc=true}srcstr3 ={ cc=world!, cc=true}dc5 =DC [ca=1, cb=Hello, cc=false]
尴尬结果真是不忍直视。

后来在http://blog.csdn.net/yuanguozhengjust/article/details/50477128才发现可以这样做。

EntityT.java

public class EntityT <T>{private int a;private String b;private boolean c;private T d;public int getA() {return a;}public void setA(int a) {this.a = a;}public String getB() {return b;}public void setB(String b) {this.b = b;}public boolean isC() {return c;}public void setC(boolean c) {this.c = c;}public T getD() {return d;}public void setD(T d) {this.d = d;}@Overridepublic String toString() {return "EntityT [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";}}
jsonentitytest.java

import java.lang.reflect.Type;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;public class jsonentitytest {public static void main(String[] args) {String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,world!', cc:true}}";//String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";//String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:\'\"Hello,word!\"\'}}";//String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:\'\"Hello,world!\"\', cc:true}}";//String dataA = "{\"a\":1, \"b\":\"Hello,world!\", \"c\":true, \"d\":{\"aa\":1}}";//String dataB = "{\"a\":2, \"b\":\"Hello,world!\", \"c\":true, \"d\":{\"ba\":1, \"bb\":\'\"Hello,world!\"\'}}";//String dataC = "{\"a\":3, \"b\":\"Hello,world!\", \"c\":true, \"d\":{\"ca\":1, \"cb\":\'Hello,world!\', \"cc\":true}}";    Gson gson = new Gson();          DC dctest = new DC(1, null, false);    String jsondctest = gson.toJson(dctest, DC.class);    System.out.println("jsondctest ="+jsondctest);        EntityT ea = gson.fromJson(dataA, EntityT.class);    EntityT eb = gson.fromJson(dataB, EntityT.class);    EntityT ec = gson.fromJson(dataC, EntityT.class);    System.out.println("ea ="+ea.toString());    System.out.println("eb ="+eb.toString());    System.out.println("ec ="+ec.toString());    System.out.println("");    if(ea.getA()==1){        Type jsonType = new TypeToken<EntityT<DA>>() {}.getType();      ea = gson.fromJson(dataA, jsonType);     System.out.println("ea ="+ea.toString());    }    if(eb.getA()==2){        Type jsonType = new TypeToken<EntityT<DB>>() {}.getType();      eb = gson.fromJson(dataB, jsonType);     System.out.println("eb ="+eb.toString());    }    if(ec.getA()==3){        Type jsonType = new TypeToken<EntityT<DC>>() {}.getType();      ec = gson.fromJson(dataC, jsonType);     System.out.println("ec ="+ec.toString());    }}}

至此已经能满足我的需求了,也没精神再找新方法了,睡觉睡觉

本文链接http://blog.csdn.net/qq_25189723/article/details/78848521

原创粉丝点击