Android Gson分析,有时数据为字符串,有时为对象
我必须解析一个json,它有时看起来像 学校名称:“马丁高中”, 领导:{ 名字:“奥斯汀”, 姓氏:“万豪”, } 有时也像 学校名称:“马丁高中”, 领导:“/leader/3434” 我试图看看是否有一个示例反序列化程序可以将“leader”处理为字符串,有时处理为对象。但是找不到Android Gson分析,有时数据为字符串,有时为对象,android,deserialization,gson,Android,Deserialization,Gson,我必须解析一个json,它有时看起来像 学校名称:“马丁高中”, 领导:{ 名字:“奥斯汀”, 姓氏:“万豪”, } 有时也像 学校名称:“马丁高中”, 领导:“/leader/3434” 我试图看看是否有一个示例反序列化程序可以将“leader”处理为字符串,有时处理为对象。但是找不到 gson是否可以实现这一点?您只需要为您的领导实施类型适配器。在read(JsonReader-In)中,使用JsonReader.peek()找出即将出现的内容,或者阅读并将其转换为Leader。这应该是相当
gson是否可以实现这一点?您只需要为您的
领导实施类型适配器。在read(JsonReader-In)
中,使用JsonReader.peek()
找出即将出现的内容,或者阅读并将其转换为Leader
。这应该是相当琐碎的
我这样做是为了锻炼
public class GsonStringOrObjectDemo {
@EqualsAndHashCode
private static class Leader {
String firstName;
String lastName;
}
private static class LeaderAdapter extends TypeAdapter<Leader> {
@Override
public void write(JsonWriter out, Leader value) throws IOException {
if (useString) {
out.value(value.firstName + ":" + value.lastName);
} else {
out.beginObject();
out.name("firstName");
out.value(value.firstName);
out.name("lastName");
out.value(value.lastName);
out.endObject();
}
useString = !useString;
}
@Override
public Leader read(JsonReader in) throws IOException {
final Leader result = new Leader();
final JsonToken type = in.peek();
switch (type) {
case BEGIN_OBJECT:
in.beginObject();
while (true) {
final String key = in.nextName();
final String value = in.nextString();
if (key.equals("firstName")) result.firstName = value;
else if (key.equals("lastName")) result.lastName = value;
else throw new JsonParseException("Unexpected key in Leader: " + key);
if (in.peek() == JsonToken.END_OBJECT) break;
}
in.endObject();
return result;
case STRING:
final String string = in.nextString();
final int pos = string.indexOf(':');
result.firstName = string.substring(0, pos);
result.lastName = string.substring(pos+1);
return result;
default:
throw new JsonParseException("Expected string or object for Leader, got: " + type);
}
}
private boolean useString;
}
public static void main(String[] args) throws Exception {
final Gson gson = new GsonBuilder().registerTypeAdapter(Leader.class, new LeaderAdapter()).setPrettyPrinting().create();
final Leader[] leaders = new Leader[10];
for (int i=0; i<leaders.length; ++i) {
leaders[i] = new Leader();
leaders[i].firstName = "First" + i;
leaders[i].lastName = "Last" + i;
}
final String json = gson.toJson(leaders);
final Leader[] leaders2 = gson.fromJson(json, Leader[].class);
Assert.assertTrue(Arrays.equals(leaders, leaders2));
}
}
公共类GsonStringOrObjectDemo{
@EqualsAndHashCode
私人静态班长{
字符串名;
字符串lastName;
}
专用静态类引线适配器扩展类型适配器{
@凌驾
public void write(JsonWriter out,Leader值)引发IOException{
如果(使用字符串){
out.value(value.firstName+“:”+value.lastName);
}否则{
out.beginObject();
out.姓名(“名字”);
out.value(value.firstName);
out.name(“lastName”);
out.value(value.lastName);
out.endObject();
}
useString=!useString;
}
@凌驾
公共领导读取(JsonReader in)引发IOException{
最终引线结果=新引线();
最终JsonToken类型=in.peek();
开关(类型){
案例开始对象:
in.beginObject();
while(true){
最后一个字符串key=in.nextName();
最终字符串值=in.nextString();
if(key.equals(“firstName”))result.firstName=value;
else if(key.equals(“lastName”))result.lastName=value;
否则抛出新的JsonParseException(“引线中的意外键:+key”);
如果(in.peek()==JsonToken.END_对象)中断;
}
in.endObject();
返回结果;
大小写字符串:
最后一个字符串=in.nextString();
final int pos=string.indexOf(“:”);
result.firstName=string.substring(0,pos);
result.lastName=string.substring(位置+1);
返回结果;
违约:
抛出新的JsonParseException(“Leader的预期字符串或对象,get:+type”);
}
}
私有布尔字符串;
}
公共静态void main(字符串[]args)引发异常{
final Gson Gson=new GsonBuilder().registerTypeAdapter(Leader.class,new LeaderAdapter()).setPrettyPrinting().create();
最终领导[]领导=新领导[10];
对于(int i=0;我编写了一个单独的类并将其添加到我的builder..builder.registerTypeAdapter(Leader.class,new LeaderAdapter());但适配器的读或写操作从未被调用过..有什么想法吗?因此,Leader是一个对象,但Strings是一个奇怪的对象时,适配器的读或写操作从未被调用..看看我更新的答案,它是有效的。在Java中,您必须始终使用对象,但我希望您能这样做。