StdSerializer
Bean class used by all standard serializers, and can also be used for custom serializers.
즉, 객체를 JSON으로 직렬화할 때 사용하는 커스텀 직렬화 로직을 구현할 수 있게 도와주는 추상 클래스이다.
ObjectMapper may not handle your domain correctly. You can structure your data in so many ways that you may find your own domain model does not correctly translate to JSON.
StdSerializer는 제네릭 타입 T를 받아들입니다. T는 직렬화하려는 대상 객체의 타입을 나타냅니다.
주요 메서드 serialize(T value, JsonGenerator gen, SerializerProvider provider)
- T : 직렬화할 객체
- JsonGenerator : JSON 출력을 만드는 데 사용하는 Jackson 객체
@Override
public void serialize(Item item, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeNumberField("id", item.getId());
jsonGenerator.writeStringField("itemName", item.getItemName());
jsonGenerator.writeNumberField("owner", item.getOwner().getId());
jsonGenerator.writeEndObject();
}
직렬화하려는 객체를 원하는 JSON 형태로 설정해 줍니다.
여기서는 Item 객체에서 User 필드 중 user.id만 반환하도록 합니다.
Serializer 생성자
public ItemSerializer() {
this(null);
}
public ItemSerializer(Class<Item> t) {
super(t);
}
- 직렬화할 객체의 타입을 부모 클래스에 전달하여 설정합니다.
- StdSerializer의 생성자를 호출하여, 직렬화할 객체의 타입을 설정합니다.
기본 생성자를 추가하지 않으면 아래와 같은 에러 메시지가 발생하면서 제대로 Serializer가 작동하지 않습니다.
2024-10-16T23:14:26.928+09:00 WARN 57058 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Error creating bean with name 'kylo.querydsl.serializer.UserSerializer':
Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'java.lang.Class<kylo.querydsl.serializer.User>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}]
직렬화(Serializer) 클래스에서 빈을 찾을 수 없어 발생한 오류입니다. StdSerializer 같은 Jackson의 커스텀 직렬화 클래스는 스프링에서 빈으로 관리되지 않기 때문에 발생할 수 있습니다.
기본 생성자를 추가하여 직렬화 클래스가 초기화될 수 있도록 해주어야 합니다.
@JsonSerializer
Annotation used for configuring serialization aspects, by attaching to "getter" methods or fields, or to value classes.
When annotating value classes, configuration is used for instances of the value class but can be overridden by more specific annotations (ones that attach to methods or fields).
@JsonSerializer 어노테이션으로 적용할 시리얼라이저를 설정합니다. (메서드나 필드에 getter가 필요함.!)
@Getter
@JsonSerialize(using = ItemSerializer.class)
public class Item {
private int id;
private String itemName;
private User owner;
}
- using 옵션으로 적용할 시리얼라이저를 설정합니다.
실습 2
User 객체에 대한 Serializer 만들기
- User 필드의 name을 username으로 반환
- LocalDatetime을 “yyyy-MM-dd” 형태로 반환
public class UserSerializer extends StdSerializer<User> {
public UserSerializer() {
this(null);
}
protected UserSerializer(Class<User> t) {
super(t);
}
@Override
public void serialize(User value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeStartObject();
gen.writeStringField("username", value.getName());
gen.writeStringField("createdAt", DateTimeFormatter.ofPattern("yyyy-MM-dd").format(value.getCreatedAt()));
gen.writeEndObject();
}
}
//===//
@Getter
@JsonSerialize(using = UserSerializer.class)
public class User {
private int id;
private String name;
private LocalDateTime createdAt;
}
참고자료
'Spring Framework > Spring' 카테고리의 다른 글
Spring MessageSource를 이용한 다국어 메시지 처리: LocaleResolver와 LocaleContextHolder 활용법 (1) | 2024.10.19 |
---|---|
Spring @RequestParam 페이징 정보 처리하기 - Pageable, @PageableDefault, sort (0) | 2024.10.19 |
Spring Scope 어노테이션으로 빈 라이프사이클 이해하기 - prototype, request, session (4) | 2024.10.13 |
스프링 FactoryBean: 생성자 주입과 필드 주입 시 프록시 객체의 동작 차이 (0) | 2024.10.12 |
Spring AOP 개념 정리 및 Aspect 적용 방법 - annotation 활용 (1) | 2024.10.10 |