杰瑞科技汇

JsonSerializer在Java中如何高效使用?

Of course! Here is a comprehensive guide to using JsonSerializer in Java, covering the modern, built-in java.json (since Java 17) and the popular third-party library Jackson.

JsonSerializer在Java中如何高效使用?-图1
(图片来源网络,侵删)

The Modern Way: java.json (Built-in, Java 17+)

Starting with Java 17, Java includes a standard API for JSON processing in the java.json package. This is the recommended approach if you're using a modern Java version and don't need advanced features or legacy support.

Key Classes:

  • JsonParser: Reads and parses JSON from sources like strings or streams.
  • JsonGenerator: Writes JSON data to destinations like strings or streams.
  • JsonReader: A pull parser that provides a simple way to read JSON documents sequentially.
  • JsonWriter: A simple way to write JSON documents sequentially.

Example: Simple Serialization (Writing JSON)

Let's serialize a simple User object to a JSON string.

The POJO (Plain Old Java Object):

// User.java
public record User(String username, int age, boolean isActive) {}

(Using a record is concise, but a regular class with getters works just as well.)

JsonSerializer在Java中如何高效使用?-图2
(图片来源网络,侵删)

The Serialization Code:

import java.io.StringWriter;
import java.util.Map;
import java.io.IOException;
import java.io.Writer;
import java.json.*;
public class JavaJsonSerializerExample {
    public static void main(String[] args) {
        User user = new User("john_doe", 30, true);
        // Use a try-with-resources block to automatically close the Writer
        try (StringWriter writer = new StringWriter()) {
            // Create a JsonGenerator
            JsonGenerator generator = Json.createGenerator(writer);
            // Start writing the JSON object
            generator.writeStartObject();
            // Write key-value pairs
            generator.write("username", user.username());
            generator.write("age", user.age());
            generator.write("isActive", user.isActive());
            // End the JSON object
            generator.writeEnd();
            generator.close(); // Important: close the generator
            // Get the JSON string from the StringWriter
            String jsonString = writer.toString();
            System.out.println(jsonString);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Output:

{"username":"john_doe","age":30,"isActive":true}

The De Facto Standard: Jackson

For most serious applications, especially in the Spring Boot ecosystem, Jackson is the go-to library. It's incredibly powerful, flexible, and feature-rich. While it's not built into the standard library, it's included as a dependency in most major frameworks.

Key Jackson Classes:

  • ObjectMapper: The central class for reading and writing JSON. You typically create one instance and reuse it.
  • JsonParser: Low-level streaming reader (similar to the standard API).
  • JsonGenerator: Low-level streaming writer (similar to the standard API).

Setup (Maven)

Add the Jackson core and databind dependencies to your pom.xml:

JsonSerializer在Java中如何高效使用?-图3
(图片来源网络,侵删)
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- Use the latest version -->
</dependency>

Example: Simple Serialization with ObjectMapper

This is much simpler than the standard API.

The POJO:

// User.java
public class User {
    private String username;
    private int age;
    private boolean isActive;
    // No-args constructor is required for deserialization
    public User() {}
    public User(String username, int age, boolean isActive) {
        this.username = username;
        this.age = age;
        this.isActive = isActive;
    }
    // Getters and Setters are required
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public boolean isActive() { return isActive; }
    public void setActive(boolean active) { isActive = active; }
    @Override
    public String toString() {
        return "User{" + "username='" + username + '\'' + ", age=" + age + ", isActive=" + isActive + '}';
    }
}

The Serialization Code:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonSerializerExample {
    public static void main(String[] args) {
        User user = new User("jane_doe", 28, false);
        // Create an instance of ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Serialize the User object to a JSON string
            // The 'writerWithDefaultPrettyPrinter()' makes the output human-readable
            String jsonString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
            System.out.println(jsonString);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

Output:

{
  "username" : "jane_doe",
  "age" : 28,
  "isActive" : false
}

Advanced Jackson Features: Customization

Jackson's real power comes from its ability to customize serialization. You can control field names, ignore fields, format dates, and handle complex objects.

Example: Customizing Serialization with Annotations

Let's enhance our User class with annotations.

import com.fasterxml.jackson.annotation.*;
import java.util.Date;
// User.java with Jackson annotations
@JsonInclude(JsonInclude.Include.NON_NULL) // Don't include null fields in the JSON
@JsonPropertyOrder({"username", "age", "isActive", "lastLogin"}) // Control property order
public class User {
    @JsonProperty("user_name") // Rename the property in JSON
    private String username;
    @JsonProperty("user_age")
    private int age;
    @JsonIgnore // This field will be completely ignored
    private String internalId;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
    private Date lastLogin;
    // Constructor, Getters, and Setters...
    // (omitted for brevity, but they are needed)
    public User(String username, int age, Date lastLogin) {
        this.username = username;
        this.age = age;
        this.lastLogin = lastLogin;
    }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public Date getLastLogin() { return lastLogin; }
    public void setLastLogin(Date lastLogin) { this.lastLogin = lastLogin; }
}

Test Code:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;
public class AdvancedJacksonExample {
    public static void main(String[] args) {
        Date now = new Date();
        User user = new User("advanced_user", 99, now);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            String jsonString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
            System.out.println(jsonString);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

Output: Notice the renamed fields, the ignored internalId, and the formatted date.

{
  "user_name" : "advanced_user",
  "user_age" : 99,
  "lastLogin" : "2025-10-27T10:30:00-0400"
}

Example: Custom JsonSerializer

Sometimes you need to write custom logic for a specific field. Let's create a custom serializer to format the age field differently.

Create the Custom Serializer:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
// The generic type <Integer> is the type of the Java field we are serializing.
public class AgeSerializer extends JsonSerializer<Integer> {
    @Override
    public void serialize(Integer age, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // Custom logic: prepend "Age: " to the value
        String formattedAge = "Age: " + age;
        gen.writeString(formattedAge);
    }
}

Annotate the POJO to use the custom serializer:

// In the User.java class
public class User {
    // ... other fields
    @JsonSerialize(using = AgeSerializer.class) // Tell Jackson to use our custom serializer
    private int age;
    // ... constructor, getters, setters
}

Run the serialization:

// Main class
User user = new User("custom_serializer_user", 42, new Date());
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(user));

Output:

{
  "username" : "custom_serializer_user",
  "age" : "Age: 42",
  "lastLogin" : "2025-10-27T10:
分享:
扫描分享到社交APP
上一篇
下一篇