@RequestBody로 List를 전달받으면?

최창효·2024년 1월 20일
post-thumbnail

@RequestBody로 값을 전달할 때 파라미터로 List를 사용한다면 다음과 같은 상황을 주의해야 합니다.

문제상황

컨트롤러

@RestController
public class MyController {
    @PostMapping("/")
    public void func(@RequestBody List<String> params) {
        System.out.println("params = " + params);
    }
}

포스트맨 요청

에러

Cannot deserialize value of type java.util.ArrayList<java.lang.String> from Object value (token JsonToken.START_OBJECT)]

왜 이럴까?

@RequestBody로 들어온 데이터는 HttpMessageConverter에 의해 변환됩니다. 그리고 이 HttpMessageConverter는 요청의 Content-Type을 기준으로 변환을 진행합니다.

Postman에서 JSON으로 데이터를 전송하면 이때 헤더의 Content-Type은 'application/json'으로 선언됩니다.
json으로 변환될 걸 기대하지만 실제로 이 변환을 받는 변수(params)는 key-value형태가 아니기 때문에 에러가 발생합니다.

해결 방안

문제를 해결하기 위해 다음과 같이 Controller를 수정할 수 있습니다.

@RestController
public class MyController {
	// @RequestBody를 받는 params변수를 key-value의 map으로 수정
    @PostMapping("/test")
    public void func2(@RequestBody Map<String, List<String>> params) {
        System.out.println("params = " + params);
    }

	// @RequestBody를 받는 params변수를 객체로 수정
    @PostMapping("/test2")
    public void func3(@RequestBody MyDto params) {
        System.out.println("dtos = " + params);
    }
}

또는 다음과 같이 json형태가 아닌 list데이터를 전달하는 방법도 가능합니다.

body는 여전히 JSON타입이지만 데이터를 json이 아닌 단순 List형태로 보내면 정상적으로 값을 받을 수 있다

결론

애초에 @RequestBody List<String> params은 객체가 아닌 List를 받을 걸 기대했는데 Postman에서 아래와 같은 Json형태를 전달했기 때문에 발생하는 문제였습니다.

{
    "params" : ["a","b","c"]
}
profile
기록하고 정리하는 걸 좋아하는 백엔드 개발자입니다.

0개의 댓글