[Spring Boot] RestTemplate (레스트템플릿) 사용

Posted by 김성철

스프링부트 - 레스트템플릿 (RestTemplate)

다른사이트에서 제공해주는 레스트풀API(restful api)에 접속하여 값 가져올 때 사용함.  
화면단에서 ajax 로 호출해서 사용해도 되지만, 서버단에서 원하는 데이터를 정제한 뒤에 화면단에 뿌려주기 위함  
SSLContext 설정부분은 인증서 오류를 안뜨게 하기 위해서  

참고사이트

https://vmpo.tistory.com/27  
https://sooin01.tistory.com/entry/RestTemplate-%EC%82%AC%EC%9A%A9%EB%B2%95  
https://advenoh.tistory.com/46  
https://velog.io/@soosungp33/%EC%8A%A4%ED%94%84%EB%A7%81-RestTemplate-%EC%A0%95%EB%A6%AC%EC%9A%94%EC%B2%AD-%ED%95%A8  
https://sjh836.tistory.com/141  
  
쿼리스트링  
https://recordsoflife.tistory.com/32  
https://m.blog.naver.com/PostView.nhn?blogId=mk1126sj&logNo=221032571275&proxyReferer=https:%2F%2Fwww.google.com%2F  
  
전달받은 값(body)를 캐스팅 하는 방법  
https://luvstudy.tistory.com/52  

라이브러리 추가

HttpComponentsClientHttpRequestFactory 클래스를 사용하려고 한다면 아래의 라이브러리를 추가해줘야함  
메이븐 URL : https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient  
  
=================================================================================================================  
implementation('org.apache.httpcomponents:httpclient:4.5')  
=================================================================================================================  

서비스로직에 레스트템플릿 구현

HttpComponentsClientHttpRequestFactory 를 생성하여, 세션타임아웃 설정  
  
RestTemplate 을 생성할때 HttpComponentsClientHttpRequestFactory 를 변수로 넣어줘서 셋팅함  
  
HttpEntity 에는 호출할 URL에 보낼 값을 넣어줌(GET 방식이 아닐경우)  
  
url 에는 호출할 URL  
  
ResponseEntity 를 생성할때는 restTemplate의 exchange 메소드를 사용해서 생성함  
	exchange(호출URL , 메소드(get,post등) , 보낼 객체 , 리턴받을 타입);  
	ResponseEntity<List<CoinPriceVO>> res = restTemplate.exchange(url.toString(), HttpMethod.GET, entity, new ParameterizedTypeReference<List<CoinPriceVO>>() {});  
리턴타입은 Object , Map ,VO등을 넣어도 되지만, VO일 경우에는 위와같이 "new ParameterizedTypeReference<List<CoinPriceVO>>() {}" 를 넣어줘야 함  
위와같이안넣어주고 CoinPriceVO 를 넣을경우 캐스팅 오류가 발생함,,변환이 안됨  
	※ 참고 URL : https://luvstudy.tistory.com/52  
  
리턴받은 res 를 찍어보면 헤더부터해서 응답값등이 포함되어 있음,  
여기서 res.getBody() 를 이용하여 요청에 대한 응답값 만을 가져옴  
  
=================================================================================================================  
  
public CoinVO getCoinPrice(CoinVO coinVO){  
  
    String coinName;  
    String url;  
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();  
    factory.setConnectTimeout(5000); //타임아웃 설정 5초  
    factory.setReadTimeout(5000);//타임아웃 설정 5초  
    RestTemplate restTemplate = new RestTemplate(factory);  
    HttpHeaders header = new HttpHeaders();  
    HttpEntity<?> entity = new HttpEntity<>(header);  
    coinName =coinVO.getMarket();  
    url = "https://api.upbit.com/v1/candles/minutes/1?market="+coinName+"&count=1";  
    //url = "https://api.upbit.com/v1/candles/minutes/1?market=KRW-BTC&count=1";  
    ResponseEntity<List<CoinPriceVO>> res = restTemplate.exchange(url.toString(), HttpMethod.GET, entity, new ParameterizedTypeReference<List<CoinPriceVO>>() {});  
    //log.info("#### resList : {}" ,res);  
    //받아온 값을 리스트로 변환  
    List<CoinPriceVO> temp= res.getBody();  
    //log.info("#### temp : {}" ,temp);  
  
    //리스트에 들어있는 값을 VO로 변환  
    CoinPriceVO coinPriceVO = temp.get(0);  
    //log.info("#### cpv : {}" ,coinPriceVO);  
    coinVO.setCoinPriceVO(coinPriceVO);  
  
    coinMapper.insertCoinPrice(coinVO);  
    return coinVO;  
}  
  
=================================================================================================================  

기본적인 설정

=====================================================================  
package com.blog.createblogpost.config;  
  
import org.springframework.boot.web.client.RestTemplateBuilder;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.http.client.BufferingClientHttpRequestFactory;  
import org.springframework.http.client.SimpleClientHttpRequestFactory;  
import org.springframework.web.client.RestTemplate;  
  
import java.time.Duration;  
  
@Configuration  
public class RestTemplateConfig {  
  
	@Bean  
	public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {  
		return restTemplateBuilder  
				.requestFactory(() ->  
						new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())  
				)  
				.setConnectTimeout(Duration.ofMillis(5000)) // connection-timeout  
				.setReadTimeout(Duration.ofMillis(5000)) // read-timeout  
				.build();  
	}  
  
}  
=====================================================================  

아래의 소스는 pki 오류를 예방하는 코드, 인증서 오류가 발생해도 무시하고 진행할수 있도록 해줌

=================================================================================================================  
  
package com.example.demo.common;  
  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.client.RestTemplate;  
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;  
  
import java.security.KeyStoreException;  
import java.security.NoSuchAlgorithmException;  
import java.security.KeyManagementException;  
import java.security.cert.X509Certificate;  
  
import javax.net.ssl.SSLContext;  
  
import org.apache.http.conn.ssl.TrustStrategy;  
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;  
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
import org.apache.http.conn.ssl.NoopHostnameVerifier;  
import org.apache.http.impl.client.CloseableHttpClient;  
import org.apache.http.impl.client.HttpClients;  
  
@Configuration  
public class RestTemplateConfig {  
	@Bean  
	public RestTemplate getRestTemplate() {  
		return new RestTemplate();  
	}  
  
	//For EPC Test : SSL verify off  
	@Bean  
	public RestTemplate restTemplate()  
			throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {  
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;  
  
		//Ignore self-signed certification  
		SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()  
				.loadTrustMaterial(null, acceptingTrustStrategy)  
				.build();  
  
		//Ignore host name verification  
		SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);  
  
		CloseableHttpClient httpClient = HttpClients.custom()  
				.setSSLSocketFactory(csf)  
				.build();  
  
		HttpComponentsClientHttpRequestFactory requestFactory =  
				new HttpComponentsClientHttpRequestFactory();  
  
		requestFactory.setHttpClient(httpClient);  
		RestTemplate restTemplate = new RestTemplate(requestFactory);  
		return restTemplate;  
	}  
}  
=================================================================================================================  

애는 ssl 오류 남

=================================================================================================================  
  
package com.example.demo.common;  
  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.client.RestTemplate;  
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;  
  
import java.security.KeyStoreException;  
import java.security.NoSuchAlgorithmException;  
import java.security.KeyManagementException;  
import java.security.cert.X509Certificate;  
  
import javax.net.ssl.SSLContext;  
  
import org.apache.http.conn.ssl.TrustStrategy;  
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;  
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
import org.apache.http.conn.ssl.NoopHostnameVerifier;  
import org.apache.http.impl.client.CloseableHttpClient;  
import org.apache.http.impl.client.HttpClients;  
  
@Configuration  
public class RestTemplateConfig {  
	@Bean  
	public RestTemplate getRestTemplate() {  
		return new RestTemplate();  
	}  
  
	//For EPC Test : SSL verify off  
	@Bean  
	public RestTemplate restTemplate()  
			throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {   //        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;  
  
		//Ignore self-signed certification  
		SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()  
				.loadTrustMaterial(null, new TrustSelfSignedStrategy())  
				.build();  
  
		//Ignore host name verification  
		SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);  
  
		CloseableHttpClient httpClient = HttpClients.custom()  
				.setSSLSocketFactory(csf)  
				.build();  
  
		HttpComponentsClientHttpRequestFactory requestFactory =  
				new HttpComponentsClientHttpRequestFactory();  
  
		requestFactory.setHttpClient(httpClient);  
		RestTemplate restTemplate = new RestTemplate(requestFactory);  
		return restTemplate;  
	}  
}  
=================================================================================================================