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

这几天遇到个解析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;
	}
	@Override
	public 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值