[Spring] @PutMapping 시 DTO 객체에 매핑이 안될 때
게시글 작성, 게시글 수정 로직을 구현하던 중 발생한 오류입니다.
각각 PostMapping, PutMapping으로 컨트롤러를 만들고, ajax로 클라이언트와 연동하려는데 게시글 수정에서만 오류가 났다.
보다시피 둘의 클라이언트 코드는 거의 비슷하다. 컨트롤러로 넘겨줄 데이터를 params에 넣어서 보낸다.
02:51:03.256 ERROR --- [http-nio-8080-exec-33] c.w.a.e.CommonsExceptionHandler.handleException:32 - + 1. Exception type: java.sql.SQLException 02:51:03.256 ERROR --- [http-nio-8080-exec-33] c.w.a.e.CommonsExceptionHandler.handleException:33 - + 2. Exception message: 부적합한 열 유형: 1111
게시글 수정 함수를 호출할 때만 해당 오류가 발생하였고,
원인은 data가 DTO객체에 매핑이 안돼서 필드가 null인 상태로 쿼리를 수행하려고 하기 때문이었다.
그런데 참 이상했다.
ajax 통신 전 params를 찍어보면 제대로 데이터들이 들어있기 때문..
그러나 컨트롤러 로그는 여전히 DTO에 매핑이 되지 않았다고 찍혔다.
02:51:03.234 TRACE --- [http-nio-8080-exec-33] c.w.a.b.c.BoardController.boardModify:128 - boardModify(BoardDTO(commId=318, userId=null, commPostTitle=null, commPostContents=null, commTempsave=null)) invoked.
단순 오타문제였으면 좋았겠지만, 애석하게도 이런 문제는 아니었다.
심지어 그와중에 commId는 또 제대로 들어온 걸 보고....이게 뭔가 싶었다.
꽤 오랜시간 혼자 씨름하다가 검색한 결과, PUT / DELETE 매핑시엔 데이터를 JSON형식으로 보내야 한다는 것을 발견했다.
해결방법은 data를 JSON 형식으로 보내고, 컨트롤러 쪽에서는 @RequestBody 어노테이션으로 받으면 된다.
$.ajax({
url: "/board/api/" + commId,
type: "PUT",
contentType: 'application/json; charset=utf-8', // 해당 코드 추가
data: JSON.stringify(params), // 해당 코드 추가
success: data => {
console.log(data);
$('#regConfirmModal').modal('hide');
$('#regModal').modal('show');
} // success
}) // .ajax
contentType을 json으로 설정하고, JSON객체의 내장함수 stringify를 사용해 데이터를 JSON형식으로 매핑한다.
public APIResponse boardModify(@ApiIgnore @RequestBody BoardDTO dto) throws ControllerException {
그리고 컨트롤러 코드에서 dto객체에 @RequestBody를 붙이면 된다!
어노테이션은 여러개를 같이 사용해도 된다. @ApiIgnore 어노테이션은 Swagger를 사용하고 있기 때문에 붙인 어노테이션이다.