Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

เมื่อไหร่ควรใช้ @JsonAnyGetter และ @JsonAnySetter ใน Java

Annotation @JsonAnyGetter อนุญาตให้ใช้ Map เป็น container สำหรับ properties ที่ต้องการ serialize เป็น JSON ส่วน @JsonAnySetter สั่งให้ Jackson เรียก setter method เดียวกันสำหรับ unrecognized fields ทั้งหมดใน JSON object (ฟิลด์ที่ไม่ได้ map ไป property หรือ setter ใน Java object)

ไวยากรณ์


public @interface JsonAnyGetter
public @interface JsonAnySetter

ตัวอย่างโค้ดครบถ้วน


import java.io.*;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.annotation.*;

public class JsonAnyGetterAndSetterTest {
    public static void main(String[] args) throws Exception {
        Employee emp1 = new Employee();
        emp1.setFirstName("Adithya");
        emp1.setLastName("Sai");
        emp1.setEmpId(125);
        emp1.getAdditionalInformation().put("technology1", "Machine Learning");
        emp1.getAdditionalInformation().put("technology2", "Robotics");
        
        ObjectMapper mapper = new ObjectMapper();
        String jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(emp1);
        System.out.println(jsonStr);
        
        System.out.println("Deserializing JSON to Object:");
        Employee emp2 = mapper.readValue(jsonStr, Employee.class);
        System.out.println("id: " + emp2.getEmpId());
        System.out.println("firstName: " + emp2.getFirstName());
        System.out.println("lastName: " + emp2.getLastName());
        System.out.println("Additional info: " + emp2.getAdditionalInformation());
    }
}

// Employee class
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"firstName", "lastName", "technologies", "empId"})
class Employee {
    @JsonProperty("EMPLOYEE_ID")
    private int empId;
    
    @JsonProperty("EMPLOYEE_FIRST_NAME")
    private String firstName;
    
    @JsonProperty("EMPLOYEE_LAST_NAME")
    private String lastName;
    
    private Map<String, String> additionalInformation = new HashMap<>();
    
    // Getters & Setters...
    public int getEmpId() { return empId; }
    public void setEmpId(int empId) { this.empId = empId; }
    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public String getLastName() { return lastName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
    
    @JsonAnyGetter
    public Map<String, String> getAdditionalInformation() {
        return additionalInformation;
    }
    
    public void setAdditionalInformation(Map<String, String> additionalInformation) {
        this.additionalInformation = additionalInformation;
    }
    
    @JsonAnySetter
    public void setAdditionalProperty(String name, String value) {
        this.additionalInformation.put(name, value);
    }
}

ผลลัพธ์


{
  "EMPLOYEE_FIRST_NAME" : "Adithya",
  "EMPLOYEE_LAST_NAME" : "Sai",
  "EMPLOYEE_ID" : 125,
  "technology1" : "Machine Learning",
  "technology2" : "Robotics"
}
Deserializing JSON to Object:
id: 125
firstName: Adithya
lastName: Sai
Additional information: {technology1=Machine Learning, technology2=Robotics}

เมื่อไหร่ควรใช้

  • @JsonAnyGetter: ต้องการ serialize dynamic properties / extension data / metadata ที่ไม่มีฟิลด์คงที่
  • @JsonAnySetter: ต้องการ deserialize JSON ที่มีฟิลด์เพิ่มเติม ไม่รู้ล่วงหน้าว่ามีฟิลด์อะไรบ้าง (flexible schema)
  • คู่กันใช้สำหรับ Open Content Models / Schema Evolution

ข้อควรระวัง

  • Map key ต้องเป็น String
  • ควรใช้ร่วมกับ @JsonInclude(Include.NON_NULL) เพื่อไม่ serialize map ว่าง
  • Type safety ต่ำกว่า POPTH ธรรมดา - ควร validate ข้อมูลหลัง deserialize