
在Java开发中,将JSON数据转换为对应的Java对象(即反序列化)是常见的操作。Gson是一个流行的Java库,用于实现这一功能。然而,如果不正确地理解JSON数据的结构与Java对象模型之间的对应关系,很容易遇到运行时错误,例如java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at path $。这个错误通常意味着Gson在尝试解析一个JSON对象时,却发现了一个字符串(或其他非对象类型),或者尝试将一个JSON的子元素当作整个对象进行解析。
考虑以下JSON数据结构:
{
  "type":"set",
  "key":"person",
  "value":{
    "name":"Elon Musk",
    "car":{
      "model":"Tesla Roadster",
      "year":"2018"
    },
    "rocket":{
      "name":"Falcon 9",
      "launches":"87"
    }
  }
}为了将上述JSON数据映射到Java对象,我们首先需要定义匹配的Java类。根据JSON的层级结构,我们可以定义Person和Value两个类:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Person  {
    String type;
    String key;
    Value value; // 注意这里是Value类型,对应JSON中的"value"对象
}import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.util.Map;
@Data
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
public class Value  {
    String name;
    Map<String, String> car;    // 对应JSON中的"car"对象
    Map<String, String> rocket; // 对应JSON中的"rocket"对象
}假设我们已经通过JsonParser将JSON字符串解析为了JsonObject:
立即学习“Java免费学习笔记(深入)”;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.StringReader;
import java.util.Map;
// 假设 input.readUTF() 提供了上述JSON字符串
String jsonString = "{\n" +
        "  \"type\":\"set\",\n" +
        "  \"key\":\"person\",\n" +
        "  \"value\":{\n" +
        "    \"name\":\"Elon Musk\",\n" +
        "    \"car\":{\n" +
        "      \"model\":\"Tesla Roadster\",\n" +
        "      \"year\":\"2018\"\n" +
        "    },\n" +
        "    \"rocket\":{\n" +
        "      \"name\":\"Falcon 9\",\n" +
        "      \"launches\":\"87\"\n" +
        "    }\n" +
        "  }\n" +
        "}";
JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
Gson gson = new Gson();
// 错误的尝试
// for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
//     Person person = gson.fromJson(entry.getValue(), Person.class); // 这里会抛出IllegalStateException
//     System.out.println(person);
// }上述被注释掉的代码片段展示了一个常见的错误模式。开发者可能误以为需要遍历JsonObject的每个条目(entry),然后将每个条目的值反序列化为Person对象。然而,这与我们的JSON结构不符:
解决这个问题的关键在于认识到:整个JSON对象(即jsonObject本身)就是我们要反序列化的Person对象。因此,我们不需要遍历它的内部条目,而是直接将整个JsonObject传递给gson.fromJson()方法。
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.StringReader;
import java.util.Map;
public class JsonToPersonConverter {
    public static void main(String[] args) {
        String jsonString = "{\n" +
                "  \"type\":\"set\",\n" +
                "  \"key\":\"person\",\n" +
                "  \"value\":{\n" +
                "    \"name\":\"Elon Musk\",\n" +
                "    \"car\":{\n" +
                "      \"model\":\"Tesla Roadster\",\n" +
                "      \"year\":\"2018\"\n" +
                "    },\n" +
                "    \"rocket\":{\n" +
                "      \"name\":\"Falcon 9\",\n" +
                "      \"launches\":\"87\"\n" +
                "    }\n" +
                "  }\n" +
                "}";
        // 1. 使用JsonParser解析JSON字符串为JsonObject
        JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
        // 2. 创建Gson实例
        Gson gson = new Gson();
        // 3. 直接将整个JsonObject反序列化为Person对象
        Person person = gson.fromJson(jsonObject, Person.class);
        // 4. 打印结果验证
        System.out.println("成功反序列化为 Person 对象:");
        System.out.println(person);
        System.out.println("Person Type: " + person.getType());
        System.out.println("Person Key: " + person.getKey());
        System.out.println("Person Value Name: " + person.getValue().getName());
        System.out.println("Person Value Car Model: " + person.getValue().getCar().get("model"));
    }
}输出结果:
成功反序列化为 Person 对象:
Person(type=set, key=person, value=Value(name=Elon Musk, car={model=Tesla Roadster, year=2018}, rocket={name=Falcon 9, launches=87}))
Person Type: set
Person Key: person
Person Value Name: Elon Musk
Person Value Car Model: Tesla Roadster正确使用Gson将JSON反序列化为Java对象,关键在于准确理解JSON数据的整体结构,并将其与Java对象模型进行一对一的映射。当整个JSON数据代表一个完整的Java对象时,应直接将该JSON数据(无论是字符串、Reader还是JsonObject)传递给gson.fromJson()方法,而不是错误地尝试迭代其内部元素。通过遵循这些原则,可以有效避免常见的IllegalStateException,确保数据转换的流畅和准确。
以上就是使用Gson将JSON对象正确反序列化为Java对象教程的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号