
在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号