Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Gson分析,有时数据为字符串,有时为对象_Android_Deserialization_Gson - Fatal编程技术网

Android Gson分析,有时数据为字符串,有时为对象

Android Gson分析,有时数据为字符串,有时为对象,android,deserialization,gson,Android,Deserialization,Gson,我必须解析一个json,它有时看起来像 学校名称:“马丁高中”, 领导:{ 名字:“奥斯汀”, 姓氏:“万豪”, } 有时也像 学校名称:“马丁高中”, 领导:“/leader/3434” 我试图看看是否有一个示例反序列化程序可以将“leader”处理为字符串,有时处理为对象。但是找不到 gson是否可以实现这一点?您只需要为您的领导实施类型适配器。在read(JsonReader-In)中,使用JsonReader.peek()找出即将出现的内容,或者阅读并将其转换为Leader。这应该是相当

我必须解析一个json,它有时看起来像

学校名称:“马丁高中”, 领导:{ 名字:“奥斯汀”, 姓氏:“万豪”, }

有时也像

学校名称:“马丁高中”, 领导:“/leader/3434”

我试图看看是否有一个示例反序列化程序可以将“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中,您必须始终使用对象,但我希望您能这样做。