어떤 이슈?
급하게 테스트해볼 이슈가 있어서 간단하게 객체를 만들고 이 객체를 json string으로 변환해야 할 일이 있었습니다.
그래서 테스트용 class를 생성하고 이를 ObjectMapper의 writeValueAsString()를 이용하여 출력해 보았는데...
아래와 같은 에러가 튀어나왔죠.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.hongjun423.toy_project.domain.Student and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
serializer 하는 과정에서 기본으로 접근 제한자가 public 이거나 getter/setter를 이용하기 때문에 인스턴스 필드를 private 등으로 선언하면 json으로 변환 과정에서 에러가 발생합니다.
해결
No serializer found for class 에러를 해결하려면 여러 가지 방법이 있는데요. 순서대로 해결방법을 알아보겠습니다.
첫 번째 방법은 ObjectMapper의 인스턴스에 세팅하여 private 필드로 접근 가능하도록 하는 것입니다.
아래와 같이 필드로 접근하고 접근 제한자 범위를 ANY로 설정해 주면 이 문제를 해결할 수 있습니다.
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
두 번째와 세 번째 방법은 json으로 변환할 class에 어노테이션을 이용해 접근 방법을 지정하는 것입니다.
두 번째 방법은 json으로 변환할 인스턴스 필드에 @JsonProperty를 필드에 선언해주는 것입니다..
아래와 같이 @JsonProperty를 필드에 적용시키면 해당 필드는 필드의 이름값을 json의 key로 이용하게 됩니다.
@JsonProperty("addr")와 같이 선언할 경우 key로 "addr"을 사용한다는 의미입니다.
이 방법을 이용할 때 한 가지 주의할 점은 json으로 변환을 원하지 않는 필드에는 @JsonIgnore을 선언해 주어야 하는 부분입니다.
public class Student {
@JsonProperty
private String name;
@JsonProperty
private int age;
@JsonProperty("addr")
private String address;
public Student() {
}
}
세 번째 방법은 class에 @JsonAutoDetect를 선언하여 private 필드에도 접근 가능하도록 지정하는 것입니다.
아래와 같이 JsonAutoDetect.Visibility.ANY로 지정하면 private 필드에도 접근하여 json으로 변환하는 데 사용하게 됩니다. ANY 외에도 DEFAULT, NON_PRIVATE, NONE, PROTECTED_AND_PUBLIC, PUBLIC_ONLY로 지정 가능합니다.
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Student {
private String name;
private int age;
private String address;
public Student() {
}
}
위 방법들의 우선순위는?
위의 세 가지 방법을 같이 사용하게 되면 우선순위대로 적용 되게 됩니다.
우선순위는 아래의 순서대로 우선 적용됩니다.
1. @JsonProperty를 이용한 필드에 선언
2. @JsonAutoDetect를 이용한 class에 선언
3. setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)를 이용한 ObjectMapper 인스턴스에 세팅
참조
https://alwayspr.tistory.com/31
https://dumdildor.tistory.com/13
'Java & 스프링 > Java' 카테고리의 다른 글
[Java] was가 여러개/멀티스레드 환경에서 중복 id체크 (0) | 2020.01.29 |
---|---|
[Java] CentOS 환경에서 openJDK 8 설치 및 환경변수 설정 (2) | 2019.12.17 |
[Java] 자바의 예외 - Exception, RuntimeException 그리고 Error (0) | 2019.11.05 |
[Java] Java의 날짜와 시간, Time API - (ZonedDateTime, LocalDateTime) (0) | 2019.10.12 |
[Java] toString() 메서드 (0) | 2019.05.01 |
댓글