JSON 在 Java 中的使用

JSON 与 Java

Java 本身不提供原生的 JSON 支持,但有许多优秀的第三方库可以处理 JSON 数据。最流行的 JSON 处理库包括 Jackson、Gson 和 org.json。

{"{}"}

Jackson

功能最强大,性能最好的 JSON 库

" "

Gson

Google 开发的简单易用的 JSON 库

📁

org.json

轻量级的 JSON 处理库

🔧

JSON-B

Java EE 标准的 JSON 绑定 API

Java JSON 库比较

Jackson

推荐

Jackson 是 Java 生态中最流行、功能最强大的 JSON 处理库,广泛应用于 Spring 等主流框架。

Maven 依赖:
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.15.2</version>
</dependency>
Gradle 依赖:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'

Gson

简单易用

Gson 是 Google 开发的 JSON 库,API 简单直观,适合初学者和简单应用场景。

Maven 依赖:
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.10.1</version>
</dependency>

org.json

轻量级

org.json 是一个轻量级的 JSON 处理库,不依赖其他第三方库,适合简单的 JSON 操作。

Maven 依赖:
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20230618</version>
</dependency>

Jackson 库使用

基本解析与序列化

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public class JacksonExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        // JSON 字符串
        String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false}";

        // 解析为 Map
        Map<String, Object> data = mapper.readValue(jsonString, Map.class);
        System.out.println("姓名: " + data.get("name"));
        System.out.println("年龄: " + data.get("age"));

        // 序列化回 JSON
        String newJson = mapper.writeValueAsString(data);
        System.out.println("JSON: " + newJson);
    }
}

使用 Java 对象

import com.fasterxml.jackson.databind.ObjectMapper;

public class User {
    private String name;
    private int age;
    private boolean isStudent;

    // 必须有无参构造函数
    public User() {}

    public User(String name, int age, boolean isStudent) {
        this.name = name;
        this.age = age;
        this.isStudent = isStudent;
    }

    // Getter 和 Setter 方法
    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 class JacksonObjectExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        // JSON 到对象
        String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false}";
        User user = mapper.readValue(jsonString, User.class);
        System.out.println("用户: " + user.getName());

        // 对象到 JSON
        User newUser = new User("李四", 25, true);
        String userJson = mapper.writeValueAsString(newUser);
        System.out.println("JSON: " + userJson);
    }
}

格式化输出

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class JacksonFormatExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        
        // 启用美化输出
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        User user = new User("王五", 28, false);
        String prettyJson = mapper.writeValueAsString(user);
        System.out.println(prettyJson);
        /* 输出:
{
"name" : "王五",
"age" : 28,
"student" : false
}
*/
    }
}

Gson 库使用

基本解析与序列化

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;

public class GsonExample {
    public static void main(String[] args) {
        Gson gson = new Gson();

        // JSON 字符串
        String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false}";

        // 解析为 Map
        Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
        Map<String, Object> data = gson.fromJson(jsonString, mapType);
        System.out.println("姓名: " + data.get("name"));

        // 序列化回 JSON
        String newJson = gson.toJson(data);
        System.out.println("JSON: " + newJson);
    }
}

使用 Java 对象

import com.google.gson.Gson;

public class GsonObjectExample {
    public static void main(String[] args) {
        Gson gson = new Gson();

        // JSON 到对象
        String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false}";
        User user = gson.fromJson(jsonString, User.class);
        System.out.println("用户: " + user.getName());

        // 对象到 JSON
        User newUser = new User("李四", 25, true);
        String userJson = gson.toJson(newUser);
        System.out.println("JSON: " + userJson);
    }
}

格式化输出

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class GsonFormatExample {
    public static void main(String[] args) {
        // 创建带格式化的 Gson 实例
        Gson gson = new GsonBuilder()
            .setPrettyPrinting() // 美化输出
            .create();

        User user = new User("王五", 28, false);
        String prettyJson = gson.toJson(user);
        System.out.println(prettyJson);
    }
}

org.json 库使用

import org.json.JSONObject;
import org.json.JSONArray;

public class OrgJsonExample {
    public static void main(String[] args) {
        // 创建 JSONObject
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "张三");
        jsonObject.put("age", 30);
        jsonObject.put("isStudent", false);

        // 添加数组
        JSONArray hobbies = new JSONArray();
        hobbies.put("阅读");
        hobbies.put("游泳");
        jsonObject.put("hobbies", hobbies);

        // 输出 JSON 字符串
        String jsonString = jsonObject.toString();
        System.out.println(jsonString);

        // 从字符串解析
        JSONObject parsedObject = new JSONObject(jsonString);
        System.out.println("姓名: " + parsedObject.getString("name"));
    }
}

格式化输出

import org.json.JSONObject;

public class OrgJsonFormatExample {
    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "张三");
        jsonObject.put("age", 30);
        jsonObject.put("address", new JSONObject()
            .put("city", "北京")
            .put("country", "中国"));

        // 缩进 4 个空格
        String formattedJson = jsonObject.toString(4);
        System.out.println(formattedJson);
    }
}

JSON 文件操作

读取 JSON 文件

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.Map;

public class JsonFileReader {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        // 从文件读取 JSON
        File file = new File("data.json");
        Map<String, Object> data = mapper.readValue(file, Map.class);

        System.out.println("数据: " + data);
    }
}

写入 JSON 文件

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class JsonFileWriter {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        // 创建数据
        Map<String, Object> data = new HashMap<>();
        data.put("name", "张三");
        data.put("age", 30);
        data.put("hobbies", new String[]{"阅读", "游泳"});

        // 写入文件
        mapper.writeValue(new File("output.json"), data);
        System.out.println("数据已保存到 output.json");
    }
}

完整的文件操作工具类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JsonFileUtils {
    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        // 配置 ObjectMapper
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
    }

    // 读取 JSON 文件
    public static Map<String, Object> readJsonFile(String filename) throws IOException {
        File file = new File(filename);
        if (!file.exists()) {
            return new HashMap<>();
        }
        return mapper.readValue(file, Map.class);
    }

    // 写入 JSON 文件
    public static void writeJsonFile(String filename, Map<String, Object> data) throws IOException {
        mapper.writeValue(new File(filename), data);
    }

    public static void main(String[] args) {
        try {
            // 示例数据
            Map<String, Object> userData = new HashMap<>();
            userData.put("name", "张三");
            userData.put("age", 30);
            userData.put("email", "zhangsan@example.com");

            // 保存数据
            writeJsonFile("user.json", userData);
            System.out.println("数据已保存");

            // 读取数据
            Map<String, Object> loadedData = readJsonFile("user.json");
            System.out.println("加载的数据: " + loadedData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

高级功能

处理复杂对象

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.ArrayList;

public class Address {
    private String city;
    private String country;

    // 构造函数、getter、setter
    public Address() {}
    public Address(String city, String country) {
        this.city = city;
        this.country = country;
    }
    // getter 和 setter 方法...
}

public class ComplexUser {
    private String name;
    private int age;
    private Address address;
    private List<String> hobbies;

    // 构造函数、getter、setter
    public ComplexUser() {}
    // getter 和 setter 方法...
}

public class ComplexObjectExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        // 创建复杂对象
        ComplexUser user = new ComplexUser();
        user.setName("张三");
        user.setAge(30);
        user.setAddress(new Address("北京", "中国"));
        user.setHobbies(List.of("阅读", "游泳", "编程"));

        // 序列化
        String json = mapper.writeValueAsString(user);
        System.out.println(json);

        // 反序列化
        ComplexUser parsedUser = mapper.readValue(json, ComplexUser.class);
        System.out.println("用户: " + parsedUser.getName());
    }
}

自定义序列化

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CustomUser {
    private String name;
    private int age;
    
    // 自定义日期序列化
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date birthDate;

    // 构造函数、getter、setter...
}

class CustomDateSerializer extends JsonSerializer<Date> {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException {
        String formattedDate = dateFormat.format(date);
        gen.writeString(formattedDate);
    }
}

实际应用场景

1. Spring Boot REST API

import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.ArrayList;

@RestController
@RequestMapping("/api/users")
public class UserController {
    private List<User> users = new ArrayList<>();

    // 获取所有用户
    @GetMapping
    public List<User> getAllUsers() {
        return users;
    }

    // 根据ID获取用户
    @GetMapping("/{id}")
    public User getUserById(@PathVariable int id) {
        return users.stream()
            .filter(user -> user.getId() == id)
            .findFirst()
            .orElse(null);
    }

    // 创建新用户
    @PostMapping
    public User createUser(@RequestBody User user) {
        user.setId(users.size() + 1);
        users.add(user);
        return user;
    }

    // 更新用户
    @PutMapping("/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User userDetails) {
        User user = getUserById(id);
        if (user != null) {
            user.setName(userDetails.getName());
            user.setAge(userDetails.getAge());
            user.setStudent(userDetails.isStudent());
        }
        return user;
    }

    // 删除用户
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable int id) {
        users.removeIf(user -> user.getId() == id);
    }
}

2. 配置文件管理

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class AppConfig {
    private Map<String, Object> config;
    private final ObjectMapper mapper = new ObjectMapper();
    private final String configFile = "config.json";

    public AppConfig() {
        loadConfig();
    }

    private void loadConfig() {
        try {
            File file = new File(configFile);
            if (file.exists()) {
                config = mapper.readValue(file, Map.class);
            } else {
                // 创建默认配置
                config = new HashMap<>();
                config.put("database", Map.of(
                    "url", "jdbc:mysql://localhost:3306/mydb",
                    "username", "root",
                    "password", "password"
                ));
                config.put("server", Map.of(
                    "port", 8080,
                    "debug", true
                ));
                saveConfig();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void saveConfig() {
        try {
            mapper.writeValue(new File(configFile), config);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Object get(String key) {
        return config.get(key);
    }

    public void set(String key, Object value) {
        config.put(key, value);
        saveConfig();
    }
}

交互式演示

在下面的演示区域中,您可以尝试 Java 对象与 JSON 字符串之间的转换。

Java 对象

JSON 字符串

注意事项

1. 异常处理

始终处理 JSON 处理过程中可能出现的异常:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class SafeJsonExample {
    public static String safeToJson(Object obj) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            System.err.println("JSON 序列化错误: " + e.getMessage());
            return "{}";
        }
    }

    public static <T> T safeFromJson(String json, Class<T> valueType) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(json, valueType);
        } catch (JsonProcessingException e) {
            System.err.println("JSON 解析错误: " + e.getMessage());
            return null;
        }
    }
}

2. 性能考虑

处理大型 JSON 数据时的优化建议:

  • 重用 ObjectMapper 实例(线程安全)
  • 对于流式处理,使用 Jackson 的 Streaming API
  • 使用 @JsonIgnore 注解忽略不需要序列化的字段
  • 考虑使用 Jackson Afterburner 模块提高性能

3. 最佳实践

  • 为 JSON 对象创建专门的 DTO 类
  • 使用注解控制序列化行为(@JsonProperty, @JsonFormat 等)
  • 在团队中统一 JSON 库的使用
  • 编写单元测试验证 JSON 序列化/反序列化