본문 바로가기

Front-end

requestBody로 JS Map 객체 넘기기

Vue에서 axios로 patch 요청을 보낼 때 request body에 JS Map 객체를 넘겼다.

간단하게 표현하면 아래와 같다.

let map = new Map();
map.set("1", 1);
map.set("2", 2);
axios.patch("/notices", map)
        .then(response => console.log(response))

그리고 SpringBoot에서는 아래와 같이 받으려 했었다.

@PatchMapping
public ResponseEntity<Void> patch(@RequestBody Map<Long, Long> ids ) {
    ...
}

그런데 controller에서 데이터가 받아지질 않았다. 해결하고 보니 이유가 간단했다.. 굉장히 바보가 된 기분.. 그래도 기억에 남기고자 기록한다.

먼저 시도해본 방법은 아래와 같다.

  1. JSON.stringfy 사용
  2. header에 contentType: 'application/json' 삽입

결론은 다안됐다.
JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환하지 Map 객체는 변환할 수 없는 것 같다.
contentType은 axios는 원래 application/json을 포함해서 날려서 이게 문제가 아닌 줄 알면서도 시도해봤다.

확실히 json 형식이 아니라 안 받아지는 것 같았다. 왜냐하면 console.log로 Map 객체를 찍어봤을 때

Map(2) {"1" => 1, "2" => 1}

이렇게 뜨는데 이게 json형식이 아니였기 때문이다.

JSON.stringfy가 안되면 어떻게 해결해야 할까 이리저리 찾아보던 중 Object.fromEntries 라는 메서드를 알게 되었다.

Object.fromEntries() 메서드는 키값 쌍 목록을 받고, 그 목록을 사용해 속성을 부여한 새로운 객체를 반환합니다. 반환된 요소 중 첫 번째는 생성할 객체의 속성 키로, 두 번째는 속성값으로 사용합니다.
Object.fromEntries()는 Object.entries()의 역을 수행합니다.

let map = new Map();
map.set("1", 1);
map.set("2", 2);
console.log(Object.fromEntries(map))

이렇게 찍어봤을 때 기존 JS Object처럼 json형태로 이쁘게 찍혀 나온다.

{1: 1, 2: 1}

당연히 SpringBoot에서도 잘 받아졌다! Map에 제네릭 타입을 Long이든 String이든 다 잘 받아지는 것도 신기했다.

아직 프론트 쪽 지식이 부족함을 많이 느꼈다. 더 열심히 하자..

참고