요즘의 소프트웨어는 대부분 서버와 Json 형태의 데이터를 주고 받습니다. Json으로 주고 받게 되면서 이종소프트웨어 간의 통신도 자유로워 질수 있었습니다. 하지만 요즘은 클라이언트 단과 서버단의 Json 통신 이외에도 서버와 서버끼리도 Restful 한 통신을 하는 경우가 많아졌습니다.
RestTemplate의 동작원리
org.springframework.http.client 패키지에 있다. HttpClient는 HTTP를 사용하여 통신하는 범용 라이브러리이고, RestTemplate은 HttpClient 를 추상화(HttpEntity의 json, xml 등)해서 제공해준다. 따라서 내부 통신(HTTP 커넥션)에 있어서는 Apache HttpComponents 를 사용한다. 만약 RestTemplate 가 없었다면, 직접 json, xml 라이브러리를 사용해서 변환해야 했을 것이다.
어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
어플리케이션에 반환된다.
출처: https://sjh836.tistory.com/141 [빨간색코딩]
Restful(서버-서버) RestTemplate
dependency
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --> <dependency> <groupId>com.fasterxml.jackson.core/groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.7</version> </dependency> | cs |
RestTemplate도 결국 내부는 httpClient를 사용합니다. (기본 설정으로 사용한다면 상관없지만 세부 설정을 위해 dependency를 추가해줍니다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package com.spring.javaconfig.controller; import java.net.URI; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import com.spring.javaconfig.bean.RestDTO; @RestController public class RestApiController { @RequestMapping(value="/rest") public Object getMethod() { String botCode="D9UD878EAJ"; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory= new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setReadTimeout(5000); clientHttpRequestFactory.setConnectionRequestTimeout(5000); clientHttpRequestFactory.setConnectTimeout(5000); HttpClient httpClient=HttpClientBuilder.create() .setMaxConnTotal(100) .setMaxConnPerRoute(5) .build(); clientHttpRequestFactory.setHttpClient(httpClient); RestTemplate restTemplate=new RestTemplate(clientHttpRequestFactory); /*UriComponentsBuilder.newInstance() .scheme("http") .host("127.0.0.1") .port("8983") .path("/solr/{botCode}/textanalysis") .queryParam("q", "faq테스트") .queryParam("rows", 1) .queryParam("knn.cinfo", true) .queryParam("knn.k", 1) .queryParam("intent", true) .queryParam("ner", false) .queryParam("log", false) .build().expand(botCode) .encode() .toUri(); queryParams 로 map객체를 이용해 한번에 쿼리스트링을 넣을수도 있다. */ return restTemplate.getForObject(UriComponentsBuilder.newInstance() .scheme("http") .host("localhost") .port("8983") .path("/solr/{botCode}/select") .queryParam("q", "faq테스트") .build().expand(botCode) .encode() .toUri(), Object.class); } } | cs |
RestTemplate은 커낵션을 열고 사용을 마친 후에 커넥션을 닫게 되면 close Wait상태가 된다고 합니다. 즉, db의 커넥션 풀과 같은 설정을 추가하여 불필요한 리소스, 성능이슈를 적절히 해결할 필요가 있습니다. 이 예제는 검색엔진인 solr를 이용하여 간단히 쿼리를 날려 결과를 받아 보는 요청입니다. 각각 메소드의 기능은 구글링해보시길...
'Web > Spring' 카테고리의 다른 글
Springboot - CommandLineRunner(커맨드라인러너) (0) | 2019.02.21 |
---|---|
Springframework QueryParameter 숨기며 뷰 리턴하는 방법 (0) | 2018.10.23 |
간단한 springframework JdbcTemplate 예제 (0) | 2018.10.05 |
Springframework @RequestBody 주의사항(?) (0) | 2018.09.30 |
springframework(스프링) Controller 작성전략(제네릭스,매핑정보상속) (0) | 2018.09.20 |