Java中如何解析和获取JSON数据:从基础到实践
在Java开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易读性和灵活性,已成为前后端数据交互、API接口响应、配置文件存储等场景的标配,本文将系统介绍Java中获取JSON数据的多种方式,从原生处理到主流库使用,帮助开发者快速JSON数据的解析与提取技巧。
JSON数据基础:认识Java中的JSON结构
在开始解析之前,先明确JSON数据的常见结构,这有助于后续针对性地选择提取方法:
- 对象(Object):无序的键值对集合,用包裹,如
{"name":"张三", "age":25}。 - 数组(Array):有序的值列表,用
[]包裹,如[{"name":"李四"}, {"name":"王五"}]。 - 值(Value):可以是字符串(
"双引号")、数字(123)、布尔值(true/false)、null,或嵌套的对象/数组。
Java中处理JSON时,核心需求是从这些结构中提取特定键(如"name")或索引(如数组第1个元素)对应的值。
原生方式:使用org.json库解析JSON
Java标准库中没有内置JSON解析工具,但可以通过org.json(第三方轻量级库)或javax.json(Java EE规范)实现原生解析,这里以org.json为例(依赖坐标:org.json:json:20231013)。
解析JSON对象:通过JSONObject获取键值对
假设JSON数据为:
{"name":"张三", "age":25, "isStudent":false, "address":{"city":"北京", "district":"海淀区"}}
解析步骤:
import org.json.JSONObject;
public class JsonObjectParse {
public static void main(String[] args) {
String jsonStr = "{\"name\":\"张三\", \"age\":25, \"isStudent\":false, \"address\":{\"city\":\"北京\", \"district\":\"海淀区\"}}";
// 1. 将字符串解析为JSONObject
JSONObject jsonObject = new JSONObject(jsonStr);
// 2. 获取简单类型值(String/Number/Boolean)
String name = jsonObject.getString("name"); // "张三"
int age = jsonObject.getInt("age"); // 25
boolean isStudent = jsonObject.getBoolean("isStudent"); // false
// 3. 获取嵌套的JSON对象
JSONObject addressObj = jsonObject.getJSONObject("address");
String city = addressObj.getString("city"); // "北京"
String district = addressObj.getString("district"); // "海淀区"
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("城市:" + city);
}
}
解析JSON数组:通过JSONArray遍历元素
假设JSON数据为:
[
{"name":"李四", "age":30},
{"name":"王五", "age":28},
{"name":"赵六", "age":35}
]
解析步骤:
import org.json.JSONArray;
import org.json.JSONObject;
public class JsonArrayParse {
public static void main(String[] args) {
String jsonStr = "[{\"name\":\"李四\", \"age\":30}, {\"name\":\"王五\", \"age\":28}, {\"name\":\"赵六\", \"age\":35}]";
// 1. 将字符串解析为JSONArray
JSONArray jsonArray = new JSONArray(jsonStr);
// 2. 遍历数组,提取每个元素(JSONObject)
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject personObj = jsonArray.getJSONObject(i);
String name = personObj.getString("name");
int age = personObj.getInt("age");
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
}
原生方式的注意事项
- 异常处理:若键不存在或类型不匹配(如用
getString()获取数字),会抛出JSONException,需用try-catch捕获。 - 灵活性不足:嵌套层级较深时,需逐层获取(如
jsonObject.getJSONObject("address").getString("city")),代码冗长。
主流库方式:使用Jackson高效处理JSON
Jackson是Java生态中最流行的JSON库之一,具有高性能、灵活性强、支持注解等特点,广泛用于Spring框架等场景,依赖坐标:com.fasterxml.jackson.core:jackson-databind:2.15.2。
将JSON字符串转为Java对象(反序列化)
Jackson的核心功能是将JSON字符串映射到Java对象(POJO),通过对象属性直接获取数据,避免逐层键值对提取。
步骤1:定义与JSON结构对应的Java类
// 嵌套的地址类
public class Address {
private String city;
private String district;
// 必须提供无参构造器(Jackson反射需要)
public Address() {}
// getter/setter(或使用Lombok简化)
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getDistrict() { return district; }
public void setDistrict(String district) { this.district = district; }
}
// 用户类
public class User {
private String name;
private int age;
private boolean isStudent;
private Address address;
// 无参构造器、getter/setter
public User() {}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public boolean isStudent() { return isStudent; }
public void setStudent(boolean student) { isStudent = student; }
public Address getAddress() { return address; }
public void setAddress(Address address) { this.address = address; }
}
步骤2:使用ObjectMapper解析JSON
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonParse {
public static void main(String[] args) throws Exception {
String jsonStr = "{\"name\":\"张三\", \"age\":25, \"isStudent\":false, \"address\":{\"city\":\"北京\", \"district\":\"海淀区\"}}";
// 1. 创建ObjectMapper实例
ObjectMapper objectMapper = new ObjectMapper();
// 2. 将JSON字符串转为User对象
User user = objectMapper.readValue(jsonStr, User.class);
// 3. 直接通过对象属性获取数据
System.out.println("姓名:" + user.getName()); // "张三"
System.out.println("年龄:" + user.getAge()); // 25
System.out.println("城市:" + user.getAddress().getCity()); // "北京"
}
}
解析JSON数组:转为List<Java对象>
对于JSON数组,Jackson可直接转为List,通过泛型指定元素类型。
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
public class JacksonArrayParse {
public static void main(String[] args) throws Exception {
String jsonStr = "[{\"name\":\"李四\", \"age\":30}, {\"name\":\"王五\", \"age\":28}]";
ObjectMapper objectMapper = new ObjectMapper();
// 使用TypeReference指定List泛型类型
List<User> userList = objectMapper.readValue(jsonStr, new TypeReference<List<User>>() {});
// 遍历List获取数据
for (User user : userList) {
System.out.println("姓名:" + user.getName() + ",年龄:" + user.getAge());
}
}
}
Jackson进阶:动态解析(无POJO时)
若JSON结构不固定或无需定义POJO,可用JsonNode动态解析,类似org.json但更灵活。
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonDynamicParse {
public static void main(String[] args) throws Exception {
String jsonStr = "{\"name\":\"张三\", \"hobbies\":[\"读书\", \"跑步\"], \"score\":{\"math\":90, \"english\":85}}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonStr);
// 获取字段值
String name = rootNode.get("name").asText(); // "张三"
// 获取数组元素
JsonNode hobbiesNode = rootNode.get("hobbies");
System.out.print("爱好:");
for (int i = 0; i < hobbiesNode.size(); i++) {
System.out.print(hobbiesNode.get(i).asText() + " "); // "读书 跑步"
}
// 获取嵌套对象字段
int mathScore = rootNode.get("score").


还没有评论,来说两句吧...