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

ความสำคัญของ @JsonView annotation ใน Jackson (Java)

คำอธิบายประกอบ @JsonView ใช้สำหรับ include/exclude property ระหว่าง serialization และ deserialization แบบ dynamic (ไดนามิก) เราต้องตั้งค่า ObjectMapper ให้รวม view type ที่ใช้เขียน JSON จาก Java object โดยใช้เมธอด writerWithView()

Syntax

@Target(value={ANNOTATION_TYPE, METHOD, FIELD})
@Retention(value=RUNTIME)
public @interface JsonView

ตัวอย่างการใช้งาน

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.core.JsonProcessingException;

public class JsonViewAnnotationTest {
    public static void main(String args[]) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        
        String jsonString = objectMapper.writerWithView(Views.Public.class)
                                       .writeValueAsString(new Person());
        String jsonStringInternal = objectMapper.writerWithView(Views.Internal.class)
                                               .writeValueAsString(new Person());
        
        System.out.println(jsonString);
        System.out.println(jsonStringInternal);
    }
}

// Person class
class Person {
    @JsonView(Views.Public.class)
    public long personId = 115;
    
    @JsonView(Views.Public.class)
    public String personName = "Raja Ramesh";
    
    @JsonView(Views.Internal.class)
    public String gender = "male";
    
    @Override
    public String toString() {
        return "Person{personId=" + personId + ", personName='" + personName + 
               "', gender='" + gender + "'}";
    }
}

// View definitions
class Views {
    static class Public {}
    static class Internal extends Public {}
}

ผลลัพธ์ (Output)

{"personId":115,"personName":"Raja Ramesh"}
{"personId":115,"personName":"Raja Ramesh","gender":"male"}

คำอธิบาย

Views.Internal extends Views.Public หมายความว่า Internal view จะรวมทุกอย่างใน Public view ด้วย (inheritance) เมื่อใช้ writerWithView(Views.Public.class) จะได้แค่ personId และ personName แต่เมื่อใช้ writerWithView(Views.Internal.class) จะได้ทั้งสามฟิลด์

กรณีการใช้งาน (Use Cases)

  • Public vs Internal API - Public API แสดงข้อมูลน้อย, Internal API แสดงมาก
  • User Roles - Admin เห็นมากกว่า User ปกติ
  • Summary vs Detail - List view แสดงสรุป, Detail view แสดงเต็ม
  • Versioning - View versions ต่างกันสำหรับ API versions

Deserialization ด้วย JsonView

สามารถใช้กับ deserialization ได้เช่นกัน:

objectMapper.readerWithView(Views.Public.class).readValue(json, Person.class);

สรุป

@JsonView ให้การควบคุม JSON output แบบ dynamic และ reusable ตาม view definition ลดความจำเป็นต้องสร้าง DTO หลายแบบสำหรับ view ต่างๆ เป็น best practice สำหรับ REST API design