Spring

Spring Controller에서 가변 json body 받기

구티맨 2021. 8. 10. 14:53

일반적으로 Controller에서 Json Body를 받을 때는 DTO 클래스를 정의하여,

 

해당 클래스를 인자로 Body값을 받습니다.

 

Jackson 라이브러리로 JSON과 POJO 간에 데이터바인딩을 이용하죠.

 

하지만, 개발을 하다보면 딱 고정된 규격이 아니라 확장가능한 유연한 규칙이 있는 가변 파라메터를 받기도 합니다.

 

저 같은 경우에는 json 바디를 받아 SQL Query를 구성하는 로직을 구현하였는데,

 

가용한 key 값들은 정해져있지만, Query 구성에 따라 전달되는 key값들과 level이 다릅니다.

 

이런 경우 아래와 같이 HashMap<String, Object>를 사용하여 Body를 받을수 있습니다.

 

@RestController
public class HashMapController {

    @PostMapping(path = "/map")
    public String mapRequest(@RequestBody HashMap<String, Object> param){
        System.out.println("param : " + param);
        return param.toString();
    }
}

아래와 같은 json으로 요청을 하면 param 변수에 json 값이 들어가게 되고, HashMap의 key값으로 value를 추출할 수 있습니다.

POST http://localhost:8080/map
Content-Type: application/json

{
  "wkt": "1",
  "ages": "2",
  "gender": "3",
  "school": {
    "name": "elementary",
    "location": "Seoul"
  }
}


POST http://localhost:8080/map

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 67
Date: Mon, 30 Aug 2021 05:38:42 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{wkt=1, gender=3, school={name=elementary, location=Seoul}, ages=2}

Response code: 200; Time: 214ms; Content length: 67 bytes

 

개발을 하면서 느낀 점은 이렇게 가변형태로 Body를 받더라도 어느 정도는 DTO로 정의가 가능합니다.

 

정의가 가능한 부분은 최대한 DTO로 정의를 하여 로직을 짜는 것이 개발/유지보수에 많은 도움이 됩니다.

 

( 실제로 DTO를 정의하지 않고 HashMap 그대로 파싱하여 로직을 구성하다보니, HashMap의 depth에 따라 3,4중의 for문에 머리가 어지러울 정도였습니다. )