Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Triển khai custom serializer với @JsonSerialize trong Jackson (Java)

Annotation @JsonSerialize khai báo custom serializer khi chuyển Java object → JSON. Implement bằng cách extends StdSerializer<T> và override serialize().

Cú pháp

@Target({ANNOTATION_TYPE, METHOD, FIELD, TYPE, PARAMETER})
@Retention(RUNTIME)
public @interface JsonSerialize {
    Class<? extends JsonSerializer<?>> using() default JsonSerializer.None.class;
}

Ví dụ hoàn chỉnh

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.*;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

public class JsonSerializeTest {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Employee emp = new Employee(115, "Adithya", new String[]{"Java", "Python", "Scala"});
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(emp);
        System.out.println(json);
    }
}

// Custom Serializer
class CustomSerializer extends StdSerializer<Employee> {
    public CustomSerializer() { this(Employee.class); }
    public CustomSerializer(Class<Employee> t) { super(t); }
    
    @Override
    public void serialize(Employee emp, JsonGenerator jgen, SerializerProvider provider) 
            throws IOException {
        jgen.writeStartObject();
        jgen.writeNumberField("id", emp.getId());
        jgen.writeStringField("name", emp.getName());
        
        // Gộp mảng languages thành một string phân cách bằng ;
        StringBuilder sb = new StringBuilder();
        for (String s : emp.getLanguages()) {
            sb.append(s).append(";");
        }
        jgen.writeStringField("languages", sb.toString());
        jgen.writeEndObject();
    }
}

// Entity với @JsonSerialize
@JsonSerialize(using = CustomSerializer.class)
class Employee {
    private int id;
    private String name;
    private String[] languages;
    
    public Employee(int id, String name, String[] languages) {
        this.id = id;
        this.name = name;
        this.languages = languages;
    }
    
    public int getId() { return id; }
    public String getName() { return name; }
    public String[] getLanguages() { return languages; }
}

Output

{
  "id" : 115,
  "name" : "Adithya",
  "languages" : "Java;Python;Scala;"
}

Các trường hợp dùng custom serializer

  • Format output đặc biệt: date format custom, mask sensitive data (credit card, password).
  • Flatten/transform structure: gộp array thành string, đổi tên field.
  • Conditional serialization: chỉ serialize field nếu thỏa điều kiện.
  • Polymorphic serialization: thêm type discriminator.

Best Practice

  • Dùng JsonGenerator API (streaming) để hiệu suất tốt, tránh build object trung gian.
  • Đăng ký qua SimpleModule cho global config: module.addSerializer(Employee.class, new CustomSerializer()).
  • Kết hợp @JsonFormat cho date/number đơn giản thay vì custom serializer phức tạp.
  • Jackson 2.12+: Hỗ trợ @JsonSerialize(converter = ...) cho converter đơn giản hơn serializer đầy đủ.