๊ด€๋ฆฌ ๋ฉ”๋‰ด

๐‘†๐‘ข๐‘›๐‘ โ„Ž๐‘–๐‘›๐‘’ ๐‘Ž๐‘“๐‘ก๐‘’๐‘Ÿ ๐‘Ÿ๐‘Ž๐‘–๐‘›โœง

[Spring] RestTemplate, UriComponentsBuilder ๋ณธ๋ฌธ

RestTemplate

 

  • Spring์—์„œ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ Rest ๋ฐฉ์‹ API๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” Spring ๋‚ด์žฅ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
  • Spring 3.0๋ถ€ํ„ฐ ์ง€์›๋˜์—ˆ๊ณ , json, xml ์‘๋‹ต์„ ๋ชจ๋‘ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    Rest API ์„œ๋น„์Šค๋ฅผ ์š”์ฒญ ํ›„ ์‘๋‹ต ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ์œผ๋ฉฐ HTTP ํ”„๋กœํ† ์ฝœ์˜ ๋ฉ”์†Œ๋“œ(ex. GET, POST, DELETE, PUT)๋“ค์— ์ ํ•ฉํ•œ ์—ฌ๋Ÿฌ ๋ฉ”์†Œ๋“œ๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • Spring Framework 5๋ถ€ํ„ฐ๋Š”  WebClient ๋ผ๋Š” ์ƒˆ๋กœ์šด HTTP ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด์˜ ๋™๊ธฐ์‹ API๋ฅผ ์ œ๊ณตํ•  ๋ฟ ๋งŒ ์•„๋‹ˆ๋ผ ํšจ์œจ์ ์ธ ๋น„์ฐจ๋‹จ ๋ฐ ๋น„๋™๊ธฐ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ง€์›ํ•˜์—ฌ, Spring 5.0 ์ดํ›„ ๋ถ€ํ„ฐ๋Š” RestTemplate๋Š” deprecated ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. (WebClient ์‚ฌ์šฉ ์ง€ํ–ฅ)

 

 

RestTemplate์˜ ํŠน์ง•

 · Spring 3.0 ๋ถ€ํ„ฐ ์ง€์›ํ•˜๋Š” Spring์˜ HTTP ํ†ต์‹  ํ…œํ”Œ๋ฆฟ
 · HTTP ์š”์ฒญ ํ›„ JSON, XML, String ๊ณผ ๊ฐ™์€ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํ…œํ”Œ๋ฆฟ
 · Blocking I/O ๊ธฐ๋ฐ˜์˜ ๋™๊ธฐ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ํ…œํ”Œ๋ฆฟ
 · RESTful ํ˜•์‹์— ๋งž์ถ”์–ด์ง„ ํ…œํ”Œ๋ฆฟ
 · Header, Content-Tpye๋“ฑ์„ ์„ค์ •ํ•˜์—ฌ ์™ธ๋ถ€ API ํ˜ธ์ถœ
 · Server to Server ํ†ต์‹ ์— ์‚ฌ์šฉ

 

 

RestTemplate ๋ฉ”์„œ๋“œ

 

 

 

Api ํ˜ธ์ถœ ํด๋ž˜์Šค ์ข…๋ฅ˜

 

  • RestTemplate
    • Spring 3๋ถ€ํ„ฐ ์ง€์› ๋˜์—ˆ๊ณ  REST API ํ˜ธ์ถœ์ดํ›„ ์‘๋‹ต์„ ๋ฐ›์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™๊ธฐ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค
  • AsyncRestTemplate
    • Spring 4์— ์ถ”๊ฐ€๋œ ๋น„๋™๊ธฐ RestTemplate์ž…๋‹ˆ๋‹ค
    • Spring 5.0์—์„œ๋Š” deprecated ๋˜์—ˆ์Šต๋‹ˆ๋‹ค
  • WebClient
    • Spring 5์— ์ถ”๊ฐ€๋œ ๋…ผ๋ธ”๋Ÿญ, ๋ฆฌ์—‘ํ‹ฐ๋ธŒ ์›น ํด๋ฆฌ์ด์–ธํŠธ๋กœ ๋™๊ธฐ, ๋น„๋™๊ธฐ ๋ฐฉ์‹์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

 

 

RestTemplate ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

 

0. ๊ฒฐ๊ณผ๊ฐ’์„ ๋‹ด์„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

1. ํƒ€์ž„์•„์›ƒ ์„ค์ •์‹œ HttpComponentsClientHttpRequestFactory ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

2. RestTemplate ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

3. header ์„ค์ •์„ ์œ„ํ•ด HttpHeader ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ ํ›„ HttpEntity ๊ฐ์ฒด์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

4. ์š”์ฒญ URL์„ ์ •์˜ํ•ด์ค๋‹ˆ๋‹ค.

5. exchange() ๋ฉ”์†Œ๋“œ๋กœ api๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

6. ์š”์ฒญํ•œ ๊ฒฐ๊ณผ๋ฅผ HashMap์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

UriComponents

 

  • URI๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” Components๋“ค์„ ํšจ๊ณผ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํด๋ž˜์Šค
  • URI์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ ๊ตฌ์„ฑ์š”์†Œ๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” URI ๊ตฌ์„ฑ์š”์†Œ์˜ ์ง‘ํ•ฉ
  • URI๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ
    •  Scheme
    • UserInfo
    • Host
    • Port
    • Path
    • Query
    • Fragment

 

UriComponentsBuilder

 

  • UriComponents ๋ฅผ Buildํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํด๋ž˜์Šค
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ์—ฐ๊ฒฐํ•˜์—ฌ URL ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ์ฆ‰ Controller๋‹จ์—์„œ addAttribute๋กœ ํ•˜๋‚˜ ํ•˜๋‚˜ ์†์„ฑ์„ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ์ด class๋ฅผ ์ด์šฉํ•˜๋ฉด ์†์‰ฝ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
 

 

์˜ˆ์ œ ์ฝ”๋“œ

//์š”์ฒญํ•˜๋Š” ๊ฒ€์ƒ‰ uri ์ƒ์„ฑ
public SearchLocalRes searchLocal(SearchLocalReq searchLocalReq){
    URI uri = UriComponentsBuilder.fromUriString(naverLocalSearchUrl)
            .queryParams(searchLocalReq.toMultiValueMap())
            .build()
            .encode()
            .toUri();

    HttpHeaders headers = new HttpHeaders();
    headers.set("X-Naver-Client-Id", naverClientId);
    headers.set("X-Naver-Client-Secret", naverClientSecret);
    headers.setContentType(MediaType.APPLICATION_JSON);

    // ์ด header๋ฅผ entity ์— ๋‹ด๊ธฐ
    HttpEntity httpEntity = new HttpEntity<>(headers);

    //responseType ์„ค์ •
    // ParameterizedTypeReference: ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์ธ์‹ํ•˜๊ณ  ์ „๋‹ฌํ•œ๋‹ค.
    // ์ž์„ธํ•˜๊ฒŒ๋Š” RestTemplate์˜ ์‘๋‹ต ํƒ€์ž…์„ ์ง€์ •ํ•  ๋•Œ ์ œ๋„ค๋ฆญ ์ •๋ณด๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์•Œ์•„์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
    // ParameterizedTypeReference์— <SearchLocalRes> ์ •๋ณด๋ฅผ ์ค˜์„œ ์ต๋ช… ์ž์‹ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ ๋‹ค.
    // (์ฐธ๊ณ ๋กœ ParameterizedTypeReference๋Š” abstract ํด๋ž˜์Šค๋ผ ์ง์ ‘ ์ƒ์„ฑ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค)
    // ์ด ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ API์˜ ์‘๋‹ต๊ฐ’์„ <SearchLocalRes> ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
   var responseType = new ParameterizedTypeReference<SearchLocalRes>(){};

    //restTemplate ํ†ตํ•ด์„œ ์š”์ฒญ๊ฐ’ ๋ฐ›๊ธฐ
    ResponseEntity<SearchLocalRes> responseEntity = new RestTemplate().exchange(
            uri,
            HttpMethod.GET,
            httpEntity,
            responseType
    );
    // ResponseEntity ํƒ€์ž…์œผ๋กœ ๋ฆฌํ„ด๋ฐ›์œผ๋ฉด ์ข‹์€์ ์€ ์ƒํƒœ์ฝ”๋“œ, ํ—ค๋”์ •๋ณด ๋“ฑ๋„ ์กฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

    // getBody๋ฅผ ํ†ตํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ return
    return responseEntity.getBody();

 

 

 

 

 

 

์ฐธ์กฐhttps://juntcom.tistory.com/141

https://blog.naver.com/PostView.naver?blogId=aservmz&logNo=222322019981