🤔 문제 발생
Request 요청을 위한 DTO로 사용하기 위한 클래스를 생성한 후 해당 객체를 ObjectMapper의 writeValueAsString() 메서드에 넣어 serialize 해서 json 데이터로 mvc에 content에 담아 POST 요청을 하는 테스트를 진행했습니다.
# PlaceRequest.java 코드
@AllArgsConstructor
public class PlaceRequest {
private PlaceType placeType;
private String placeName;
private String address;
private String phoneNumber;
private Integer capacity;
private String memo;
public static PlaceRequest of(
PlaceType placeType,
String placeName,
String address,
String phoneNumber,
Integer capacity,
String memo
) {
return new PlaceRequest(placeType, placeName, address, phoneNumber, capacity, memo);
}
}
위 코드의 static 메서드인 of()로 만든 객체를 ObjectMapper.writeValueAsString()에 넣어 serialize를 진행했고, 아래와 같은 오류가 발생했습니다.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class
🙆🏻♂️ 시도 / 해결
1. PlaceRequest 클래스에 빈 생성자가 존재하지 않으면 Serializer가 작동하지 않는다.
@NoArgsConstructor
@AllArgsConstructor
public class PlaceRequest {
/* 코드생략 */
}
@NoArgsConstructor 애노테이션을 붙여 비어있는 생성자를 만들어줬습니다. 그리고 다시 실행했을 때의 결과는 동일한 예외가 발생되었습니다.
JackSon에서 Deserialize(역직렬화, json -> Object)를 할 때는 기본 생성자로 객체를 생성한 후 필드 값을 찾아서 바인딩해준다고 합니다. 하지만 우리가 하려는 과정은 Deserialize가 아닌 Serialize였기 때문에 사실상 지금은 @NoArgsConstructor가 아무런 효과가 없었습니다.
2. serialize를 하는 과정에서 PlaceRequest 클래스의 필드에 접근하게 되는데, 이때 public 접근제한자 또는 getter를 통해서 접근하게 된다.
여기서 2가지 방법을 시도해볼 수 있었습니다.
(1) 필드를 모두 public으로 바꿔보자
@AllArgsConstructor
public class PlaceRequest {
public PlaceType placeType;
public String placeName;
public String address;
public String phoneNumber;
public Integer capacity;
public String memo;
/* 코드 생략 */
}
테스트를 돌려보니 통과하는 것을 볼 수 있습니다.
(2) 필드는 그대로 private로 두고, Getter를 만들어보자
@Getter
@AllArgsConstructor
public class PlaceRequest {
private PlaceType placeType;
private String placeName;
private String address;
private String phoneNumber;
private Integer capacity;
private String memo;
}
이 방법도 동일하게 테스트가 통과되는 것을 볼 수 있습니다. 저는 private 필드를 사용하기 위해서 두 번째 방법을 사용해서 코드를 작성했습니다.
💡 알게된 점
JackSon을 사용해서 Serialize(Object -> json)할 때는 필드를 public으로 지정하거나 private으로 해두었다면 JackSon이 해당 필드에 접근할 수 있도록 Getter를 만들어주어야 합니다.
반대로 Deserialize(json -> Object)를 할 때는 비어있는 기본 생성자(NoArgsConstructor)로 객체를 생성하기 때문에 반드시 기본 생성자를 클래스 안에 만들어줘야 합니다.
사실 해결 방법에는 @JsonProperty를 필드에 붙여주는 방법도 찾았던 거 같은데, 이 부분은 나중에 따로 시간을 내서 알아보고자 합니다.
'🧑🏻💻 Dev > 오류해결' 카테고리의 다른 글
Mustache 사용해서 html 파일 읽을 때 한글 깨짐 (0) | 2023.06.08 |
---|---|
[오류해결] IntelliJ 커스텀 properties 자동완성 안되는 오류 (0) | 2023.04.27 |
[오류해결] JSP img GET 요청 시 한글 깨짐 (0) | 2023.03.14 |
[오류해결] 로컬에 있는 이미지 파일 JSP에서 사용하기 (0) | 2023.03.02 |
[MAC M1] MariaDB ERROR 2002 (HY000): Can't connect to local server through socket '/tmp/mysql.sock' 해결 (3) | 2023.02.28 |