Hướng dẫn xử lý và sắp xếp trường JSON trong Java

Khi làm việc với JSON trong Java, việc kiểm soát cách dữ liệu được ánh xạ và hiển thị là rất quan trọng. Dưới đây là các kỹ thuật phổ biến để xử lý annotation JSON và kiểm soát thứ tự trường đầu ra.

1. Các Annotation JSON cơ bản

Để quản lý quá trình serialize và deserialize, chúng ta thường sử dụng các annotation sau:

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class ExampleDTO {
    
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createdDate;
    
    @JSONField(name = "AlarmTime")
    private Long alarmTime;
    
    @JsonIgnore
    private String parentIdsStr;
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String optionalField;
}

Giải thích các annotation:

  • @JsonIgnoreProperties(ignoreUnknown = true): Bỏ qua các trường không xác định khi deserialize
  • @JSONField: Đặt tên tùy chỉnh cho trường JSON (FastJSON)
  • @JsonIgnore: Loại bỏ trường khỏi quá trình serialize
  • @JsonInclude(JsonInclude.Include.NON_NULL): Chỉ bao gồm trường khi giá trị không null

2. Duyệt tất cả key-value trong JSONObject

Để lấy tất cả các cặp key-value từ một đối tượng JSON:

JSONObject sourceObject = restdataJsonObj.getJSONObject("CARD_OUT");
Iterator<String> keyIterator = sourceObject.keySet().iterator();

while (keyIterator.hasNext()) {
    String currentKey = keyIterator.next();
    Integer currentValue = sourceObject.getIntValue(currentKey);
    // Xử lý key và value tại đây
}

3. Kiểm soát thứ tự trường JSON

Mặc định, Jackson sắp xếp theo thứ tự khai báo, còn FastJSON sắp xếp theo thứ tự từ điển. Tuy nhiên, trong một số trường hợp (ví dụ: mã hóa chữ ký cho Nginx), chúng ta cần kiểm soát thứ tự này.

3.1. Jackson - Sử dụng @JsonPropertyOrder

public class JacksonExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        
        // Mặc định: theo thứ tự khai báo
        Cat1 cat1 = new Cat1("sleep", "Mimi", 1);
        System.out.println(mapper.writeValueAsString(cat1));
        
        // Tùy chỉnh thứ tự
        Cat2 cat2 = new Cat2("eat", "Mimi002", 2);
        System.out.println(mapper.writeValueAsString(cat2));
    }
}

@Data
@AllArgsConstructor
class Cat1 {
    private String hobby;
    private String name;
    private Integer age;
}

@Data
@AllArgsConstructor
@JsonPropertyOrder({"name", "age", "hobby"})
class Cat2 {
    private String hobby;
    private String name;
    private Integer age;
}

3.2. FastJSON - Sử dụng @JSONField và @JSONType

public class FastjsonExample {
    public static void main(String[] args) {
        // Mặc định
        Dog1 dog1 = new Dog1("eat", "Dudu001", 1);
        System.out.println(JSON.toJSONString(dog1));
        
        // Sử dụng ordinal
        Dog2 dog2 = new Dog2("eat", "Dudu002", 2);
        System.out.println(JSON.toJSONString(dog2));
        
        // Sử dụng orders
        Dog3 dog3 = new Dog3("eat", "Dudu003", 3);
        System.out.println(JSON.toJSONString(dog3));
    }
}

@Data
@AllArgsConstructor
class Dog1 {
    private String hobby;
    private String name;
    private Integer age;
}

@Data
@AllArgsConstructor
class Dog2 {
    @JSONField(ordinal = 3)
    private String hobby;
    @JSONField(ordinal = 2)
    private String name;
    @JSONField(ordinal = 1)
    private Integer age;
}

@Data
@AllArgsConstructor
@JSONType(orders = {"name", "age", "hobby"})
class Dog3 {
    private String hobby;
    private String name;
    private Integer age;
}

Lưu ý quan trọng: Khi parse chuỗi JSON thành đối tượng JSONObject, để giữ nguyên thứ tự trường, hãy sử dụng tham số Feature.OrderedField:

JSONObject parsed = JSON.parseObject(jsonString, Feature.OrderedField);

Điều này đặc biệt hữu ích khi bạn cần duy trì thứ tự trường gốc sau khi parse.

Thẻ: Jackson fastjson JSON Java annotation

Đăng vào ngày 22 tháng 7 lúc 00:38