ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RestTemplate Post Request - RestTemplate Hands On 4
    Spring Framework/RestTemplate 2023. 9. 24. 00:01

    개요

    이전 글에서는 RestTemplate을 활용하여 Get 요청의 QueryParam, PathVariable, Header등에 대해 학습했었습니다.

    이번 글에서는 RestTemplate Post Request에 대해 학습해 보겠습니다.

     

     

    RestTemplate Post로 요청 보내기

    @RestController
    class RestTemplatePostTestController {
    
        val baseUrl = "http://localhost:8080"
    
        @PostMapping("post-test")
        fun postTest() {
            val apiPath = "/post-test-call"
            val restTemplate = RestTemplate()
            val person = Person()
    
            val headers = HttpHeaders()
            headers.contentType = MediaType.APPLICATION_JSON
    
            val request = HttpEntity<Person>(
                person,
                headers
            )
    
            val responseEntity = restTemplate.postForEntity(
                baseUrl + apiPath,
                request,
                Person::class.java,
            )
            println(responseEntity.body)
        }
    
        @PostMapping(
            value = ["post-test-call"],
            consumes = ["application/json"],
            produces = ["application/json"],
        )
        fun postTestCall(@RequestBody person: _Person): ResponseEntity<_Person> {
            println(person)
            return ResponseEntity.ok(
                _Person(
                    id = 2,
                    name = "changedName",
                )
            )
        }
    }
    
    data class Person(
        val id: Int = 1,
        val name: String = "name",
        val extraColumn: String = "test",
    )
    
    data class _Person(
        val id: Int,
        val name: String,
    )

    String으로 따로 형변환 없이 person 객체를 넘겨서 바로 전송할 수 있습니다.

     

    그 후 postForEntity를 활용하여 request를 보낼 수 있습니다.

     

    이전글에서 봤던 것처럼 postForEntity대신 postForObject도 활용해 볼 수 있습니다. (단, ResponseEntity로 래핑 되어 반환되지 않음)

     

     

    이때 header에 contentType을 명시하지 않으면 415 상태코드가 반환됩니다.

    HttpClientErrorException$UnsupportedMediaType: 415

     

     

    호출 결과

    _Person(id=1, name=name)
    Person(id=2, name=changedName, extraColumn=test)

     

    postForLocation

    postForLocation을 활용하여 새 자원의 URI를 받아올 수 있습니다.

    Location 헤더의 반환값을 가져옵니다.

     

        @PostMapping("post-location-test")
        fun postLocationTest(){
            val apiPath = "/post-location-test-call"
            val restTemplate = RestTemplate()
            val person = Person()
    
            val headers = HttpHeaders()
            headers.contentType = MediaType.APPLICATION_JSON
    
            val request = HttpEntity<Person>(
                person,
                headers
            )
    
            val uri = restTemplate.postForLocation(
                baseUrl + apiPath,
                request,
                Person::class.java,
            )
            println(uri)
        }
    
        @PostMapping("post-location-test-call")
        fun postLocationTestCall(): ResponseEntity<Unit>{
    //        throw IllegalArgumentException()
            val uri = URI.create("/created-uri")
            return ResponseEntity.created(uri).build()
        }

    달라진 부분은 postForLocation을 활용하는 부분과 테스트를 위한 api에서 created를 활용하는 부분입니다.

     

     

    호출 결과

    /created-uri

     

    예외가 발생하면 어떻게 될까?

     

    postForLocation의 내부 메서드의 마지막 반환문입니다.

    return (headers != null ? headers.getLocation() : null);

    null이 반환되지 않고 그래도 예외가 전파된다 (사용 시에는 예외 처리에 주의해야겠다는 생각이 듭니다.)

    헤더가 없는 경우에만 null이 반환됩니다!

     

     

    참고자료

    https://www.baeldung.com/spring-resttemplate-post-json

    https://howtodoinjava.com/spring-boot2/resttemplate/resttemplate-post-json-example/

     

    댓글

Designed by Tistory.