[SpingBoot] @RequestBody 데이터바인딩이 안될 때 (feat.null)
view단에서 Ajax를 사용하여 비동기통신을 하고 위 사진의 객체타입의 데이터를 보내는데
서버에서 만든 DTO에 매핑이 되지않아 null값이 떨어지는 문제가 발생하였다.
프런트에서 보내는 객체 구조에 맞게 DTO도 구성하였는데 계속 데이터 매핑이 이루어지지 않았고
해결하던 중 @JsonProperty("data명")을 사용하니 우선 해결이 되었다.
다른 하나의 방법은 HalJsonType으로 명시를 해주고 보내니 또 파싱이 잘되었다.
그런데 무슨 문제때문인지 궁금해서 구글링을 시작.....
- Json을 이용한 Ajax기능이나 Rest Api를 이용하면 @RequestBody와 @ResponseBody를 이용하게 되는데
이 2개의 어노테이션을 명시하게 되면 스프링의 메시지 컨버터라는 인터페이스가 동작하여 Http요청이나 응답을
메세지로 변환하여 준다.
컨트롤러에서 파라미터를 받을때 @RequestBody를 입력하게 되면 파라미터 타입에 맞는 메세지컨버터가 동작하여
요청 본문을 해당 파라미터에 바인딩 해준다. (@ResponseBody를 입력하는 경우에도 마찬가지로 리턴 타입에 맞는
메시지 컨버터가 동작하여 리턴해줌)
나는 Json타입의 데이터를 컨트롤러로 요청했기 때문에 MappingJacksonHttpMessageConverter가 Jackson의 Object를 이용해서 Json과 자바 오브젝트 사이의 데이터 변환을 도와준다. (미디어 타입은 application/json)이다.
보통 DTO를 만들면 lombok을 사용하여 getter/setter를 자동으로 생성하게 되는데
Controller에서 json을 담은 request를 전달 받으면 스프링에서는 Jackson을 이용해서 자바객체로 만들어준다. 이 때 setter/ getter를 이용해서 데이터를 바인딩 해주는데 가끔 lombok이 만들어주는 setter의 규칙이 지켜지지 않으면
setter의 메서드 명이 엉뚱하게 만들어지고 Jackson이 setter메서드를 호출하지 못하면서 데이터가 바인딩 되지 않는 이슈가 있는것같았다.
그래서 @JsonProperty와 HalJsonType설정을 모두 없앤뒤에 DTO 변수명을 바꾸어서 다시 테스트를 하니
Data가 잘 바인딩 되어졌다. (Test를위해 스네이크 표기법(snake_case)을 사용)
그러니 만약 통신하는 json데이터의 구조와 잘 맞추었음에도 Data바인딩이 이루어지지 않고
null값이 떨어진다면 이런 이슈를 한번 생각해보고 접근하는것도 괜찮은것같다.
다른 블로그 포스팅글의 해결방법 중
직접 getter/setter를 만들어서 사용하는 방법도 있다고하니 여러가지 방법을 알아두는 것도 좋을것같다
참조 블로그 : https://darkstart.tistory.com/299
아니면 앞서 설명한 @JsonProperty어노테이션을 사용하여서 request 요청 시 받아오는 json data property이름을 명시 하는 방법도 있다.
HalJsonType이 어떤 관계가 있기에 해결되었는지는 아직 공부하지 못했지만 시간이 나는데로 좀 더 내용도 다듬고
추가 설명을 기록해놔야겠다.