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.