인프런 커뮤니티 질문&답변
자주 나오는 질문 - DTO에 @Allargs, @Noargs 문제
작성
·
851
·
수정됨
0
실행할 때 IntelliJ IDEA 가 아닌 Gradle로 돌려야 합니다
답변 1
0
구파고
지식공유자
해당 질문이 많이 나와서, 찾아 봤었는데 버전이나 환경, 세팅에 따라서 다른것 같고, 추가적인 어노테이션을 붙이는걸로 가이드 드렸었는데 원인이 저 부분이었군요!!
공유해주셔서 감사합니다. 다른분들한테도 많이 도움이 될꺼 같네요!






저 문제가 원인일 수도 있고, 아닐 수도 있는 것 같더라고요.. 그래서 정리해봤습니다.
틀린 부분 있으면 피드백 부탁드립니다!
@RequestBody
파라미터에
@RequestBody가 있으면스프링은
하지만 다음과 같이 애노테이션을 사용하면 문제가 될 수 있는게, 명시된 기본 생성자가 없을 때
RequestResponseBodyMethodProcessor(ArgumentResolver)가MappingJackson2HttpMessageConvertor를 이용해서 역직렬화를 수행하는데,이때 기본적으로는 기본 생성자로 DTO를 생성해서 기본생성자가 필요합니다.
하지만
@JsonProperty, @JsonAutoDetect등을 이용한Property기반 클래스이거나, 생성자가 위임된 경우라면 필요하지 않습니다.@Builder애노테이션을 사용하면@AllArgsConstructor(access = AccessLevel.PRIVATE)이 붙게 됩니다.따라서 기본 생성자가 만들어지지 않고, 역직렬화 시 기본 생성자가 없어 역직렬화 에러가 발생합니다.
@Builder를 제거해주면 됩니다.리플렉션을 사용해 필드에 값을 넣어주므로,
@Getter와 @Setter둘 중 하나만 있으면 됩니다.기본 생성자만 있고 getter 가 없다면, deserialize 불가능합니다.
https://jenkov.com/tutorials/java-json/jackson-objectmapper.html#how-jackson-objectmapper-matches-json-fields-to-java-fields
다음 글을 찾아보면,
기본적으로 Jackson은 JSON 필드의 이름을 Java 오브젝트의 getter 및 setter 메서드와 일치시켜 JSON 오브젝트의 필드를 Java 오브젝트의 필드에 매칭합니다. Jackson은 getter 및 setter 메서드 이름의 "get" 및 "set" 부분을 제거하고 나머지 이름의 첫 문자를 소문자로 변환합니다.
예를 들어 brand라는 JSON 필드는 getBrand() 및 setBrand() 라는 Java getter 및 getter 메서드와 일치합니다. engineNumber라는 JSON 필드는 getEngineNumber() 및 setEngineNumber()라는 getter 및 setter와 일치합니다.
다른 방식으로 JSON object 필드를 Java object 필드와 일치시켜야 하는 경우 custom serializer 및 deserializer를 사용하거나 많은 Jackson Annotation 중 일부를 사용해야 합니다.
라고 나와있습니다.
@ResponseBody
객체를 Json으로 직렬화할 때는
@Getter가 필요합니다(정리한 내용은 기본적으로 인스턴스 변수가 private일 때를 가정한 것입니다. Getter 없이도 public이면 직렬화가 가능합니다)
출처
https://www.one-tab.com/page/RTm8ARImR9iXDFNOnKdIzA
https://projectlombok.org/features/Builder