Engineering/Spring

POST request RestTemplate with MultiValue

산책散策 2025. 1. 7. 12:06
728x90

POST API body 에 여러 데이터를 보낼때 가끔씩 설정 실수를 해서 정리해본다.

 

아래와 같은 json 형태의 데이터를 body 로 보내려고 한다.

{
    "name": "홍길동",
    "age": 18,
    "content": "자세한 내용 : "
}

 

    @Test
    void sendToUrlTest() {
        String url = "http://abc.com/send/mail";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("name", "홍길동");
        body.add("age", 18);
        body.add("content", "자세한 내용 : ");
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(body, headers);
        String response = restTemplate.postForObject(url, request, String.class);

        log.info("response : {}", response);
    }

 

header 는 ContentType 을 "application/json" 으로 지정하고, Map 형태로 여러 데이터를 추가 후 HttpEntity 를 구성해서 postForObject() 를 호출하면 다음과 같은 "Bad Request" 오류가 나온다. body 파라미터가 먼가 이상한가 보다.

org.springframework.web.client.HttpClientErrorException$BadRequest: 400 : "{"timestamp":"2025-01-07T01:37:31.862+00:00","status":400,"error":"Bad Request","path":"/send/mail"}"

at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:101)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:168)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:819)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:777)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:437)

 

오류가 난 원인은 ContentType 을 json 으로 지정했는데, HttpEntity 를 Map 객체로 body 를 구성했기 때문이다. 이런식으로 MultiValueMap 객체를 사용하는 경우는 ConentType 이 "application/x-www-form-urlencoded" 이면 된다. ( https://www.baeldung.com/rest-template ) 또는 파일 업로드할때 많이 사용한느 "multipart/form-data" 에서 사용된다.

 

그래서 HttpEntity 파라미터를 Json String 형태로 바꿔줘야 하는데, 다음과 같이 JsonString 을 직접 작성하거나 아니면 JSONObject 객체를 이용하자.

    @Test
    void sendToUrlTest() throws JSONException {
        String url = "http://abc.com/send/mail";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        JSONObject body = new JSONObject();
        body.put("name", "홍길동");
        body.put("age", 18);
        body.put("content", "자세한 내용 : ");
        HttpEntity<String> request = new HttpEntity<>(body.toString(), headers);

/*
        String bodyJson = "{\n" +
            "    \"name\": \"홍길동\",\n" +
            "    \"age\": 18,\n" +
            "    \"content\": \"자세한 내용 : \"\n" + "}";
        HttpEntity<String> request = new HttpEntity<>(bodyJson, headers);
*/
        String response = restTemplate.postForObject(url, request, String.class);

        log.info("response : {}", response);
    }

 

 

- 참고

https://stackoverflow.com/questions/4075991/post-request-via-resttemplate-in-json