java - Gson:非法状态异常:需要一个 int,但 NAME 在第 1 行第 3 列

标签 java json gson

我想为 Student 类定义自己的序列化和反序列化方法,因此我扩展了 TypeAdapter 并重写了它的方法,但现在反序列化不起作用。为什么会出现这种情况?

public class GSONFormat {

@Test
public void run()
{
    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(Student.class, new StudentAdapter());
    Gson gson = builder.create();
    Student s = new Student();
    s.setAge(11);
    s.setName("hiway");
    System.out.println(gson.toJson(s));
    String str = "{\"age\":11,\"name\":\"hiway\"}";
    s = gson.fromJson(str, Student.class);
    System.out.println(s);
}
}

class Student{
    private int age;
    private String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

class StudentAdapter extends TypeAdapter<Student>
{

    @Override
    public void write(JsonWriter out, Student s) throws IOException {
        out.beginObject();
        out.name("age");
        out.value(s.getAge());
        out.name("name");
        out.value(s.getName());
        out.endObject();
    }

    @Override
    public Student read(JsonReader in) throws IOException {
        in.beginObject();
        Student s = new Student();
        s.setAge(in.nextInt());
        s.setName(in.nextString());
        in.endObject();
        return s;
    }
}

最佳答案

正如 Matt Ball 所评论的,如果你没有充分的理由,那么编写你的类型适配器根本不是一个好主意。如果删除此行:

builder.registerTypeAdapter(Student.class, new StudentAdapter());

您的解析将毫不费力地进行。但是,您可能有兴趣进一步了解可以使用类型适配器做什么。所以我给你一个可能的实现。请记住,如果您的类 Student 变得更加复杂,编写自己的类型适配器可能会很困难。还不如让Gson自己做事。无论如何,这里有一些可以修补你的代码的东西(在Java7下编译,如果你使用较低版本,请用if链更改switch)。

class StudentAdapter extends TypeAdapter<Student>
{

    @Override
    public void write(JsonWriter out, Student s) throws IOException {
        out.beginObject();
        out.name("age");
        out.value(s.getAge());
        out.name("name");
        out.value(s.getName());
        out.endObject();
    }

    @Override
    public Student read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
          }


        in.beginObject();
        Student s = new Student();
        while (in.peek() == JsonToken.NAME){
            String str = in.nextName();
            fillField(in, s, str);
        }


        in.endObject();
        return s;
    }

    private void fillField(JsonReader in, Student s, String str)
            throws IOException {
        switch(str){
            case "age": s.setAge(in.nextInt());
            break;
            case "name": s.setName(in.nextString());
            break;
        }
    }
}

关于java - Gson:非法状态异常:需要一个 int,但 NAME 在第 1 行第 3 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19129199/

相关文章:

javascript - 当我想从steam市场获取json时,jquery json错误

ios - JSON POST Web 服务中的多个 Json 对象和 3 个字符串

java - 如何解析键名是整数的json

java - Gradle 找不到测试

java - 如何为变量分配列表中的值?

javascript - 如何让 getJSON 在运行其余代码之前等待?

json - 使用 @ResponseBody 自定义 HttpMessageConverter 来做 Json 事情

android - 改造 - 在将其解析为 json 之前从响应主体中删除一些无效字符

java - 加载已捆绑在 .jar 中的文件?

java - 如何将java应用程序发送到系统托盘?