คำอธิบายประกอบ @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