목차
Open API를 사용하다 보면 공식문서에 HttpURLConnection이나 RestTemplate가 항상 등장한다.
따라서 이 두 클래스에 대해 알아보고자 한다.
HttpURLConnection과 RestTemplate
HttpURLConnection과 RestTemplate은 자바 클래스로 HTTP 리퀘스트를 만들때 사용한다.
HttpURLConnection
HttpURLConnection 클래스는 URLConnection을 구현한 클래스이기 때문에 먼저 URLConnection 부터 알아보자
URLConnection
- URLConnection은 웹을 통해 데이터를 주고 받는데 사용된다. (RFC 2616을 따름)
- 사용자 인증이나 보안이 설정되어 있지 않은 웹서버에 접속하여 파일 등을 다운로드하는데 많이 사용한다.
- URLConnection은 리소스에 연결하기 전에 구성 되어야 한다.
- URLConnection 인스턴스는 재사용 될 수 없다. 각 리소스에 대한 커넥션 마다 다른 인스턴스를 사용해야 한다.
HttpURLConnection
- java.net.HttpURLConnection 클래스는 URLConnection을 구현한 클래스 (java.net 클래스에서 제공하는 URL 요청을 위한 클래스)
- 데이터의 타입이나 길이는 거의 제한이 없다.
- 주로 미리 길이를 알지 못하는 스트리밍 데이터를 주고 받는데 사용된다.
- http URL을 처리할 때 도움이 되는 몇 가지 추가적인 메서드를 가지고 있다.
- 요청 방식을 확인 or 설정, redirect 여부 결정, 응답 코드와 메시지를 Read , 프록시 서버가 사용되었는지 여부 확인 메서드 등을 가지고 있다.
- 다양한 HTTP 응답 코드에 해당하는 상수 값들이 정의되어있다.
- URLConnection 클래스의 getPermission() 메서드를 오버라이드해놓았다.
★ URLConnection 클래스와 마찬가지로 생성자가 protected로 선언되어있기 때문에 기본적으로는 개발자가 직접 HttpURLConnection 객체를 생성할 수 없다.
하지만 http URL을 사용하는 URL 객체의 openConnection() 메서드가 리턴하는 URLConnection 객체는 HttpURLConnection의 인스턴스가 될 수 있기 때문에 리턴된 URLConnection을 다음처럼 HttpURLConnection으로 캐스팅해서 사용한다.
ex )
URL u = new URL("http://www.naver.com");
HttpURLConnection http = (HttpURLConnection) u.openConnection();
URLConneciton vs HttpURLConnection
간단히 정리하자면 둘 차이는 다음과 같다.
URLConnection 부모클래스다.
HttpURLConnection은 상속된 클래스로 더 많은 API를 사용할 수 있으며 HTTP나 HTTPS 를 다룰때 사용하면 된다.
cf) HttpsURLConnection도 상속된 클래스인데 더 많은 API를 사용가능하며 HTTPS만 다룰때 사용하면 된다.
실제로 사용은 다음과 같이 한다.
- new URL("http:// ....")
- openConnection()
- URLConnection
- getInputStream, getOutputStream
- InputStream, OutputStream 처리
문제점
- 응답코드가 4xx 거나 5xx 면 IOException 이 터진다.
- 타임아웃을 설정할 수 없다.
- 쿠키 제어가 불가
RestTemplate
spring 3.0 부터 지원한다. 스프링에서 제공하는 http 통신에 유용하게 쓸 수 있는 템플릿이며, HTTP 서버와의 통신을 단순화하고 RESTful 원칙을 지킨다. jdbcTemplate 처럼 RestTemplate 도 기계적이고 반복적인 코드들을 깔끔하게 정리해준다. 요청보내고 요청받는데 몇줄 안될 정도..
- 기계적이고 반복적인 코드를 최대한 줄여줌
- RESTful형식에 맞춤
- json, xml 를 쉽게 응답받음
connection pool
RestTemplate은 기본적으로 connection pool을 사용하지 않는다
따라서 연결할 때 마다, 로컬 포트를 열고 tcp connection 을 맺는다. 이때 문제는 close() 이후에 사용된 소켓은 TIME_WAIT 상태가 되는데, 요청량이 많다면 이런 소켓들을 재사용하지 못하고 소켓이 오류나서 응답이 지연된다.
이런 경우 connection pool 을 사용해서 해결할 수 있는데, DBCP마냥 소켓의 갯수를 정해서 재사용하는 것이다. RestTemplate 에서 connection pool 을 적용하려면, 다음과 같이 HttpClient 를 만들고 setHttpClient() 를 해야한다.
- setMaxConnPerRoute : IP,포트 1쌍에 대해 수행 할 연결 수를 제한한다.
- setMaxConnTotal : 최대 오픈되는 커넥션 수를 제한한다.
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(5000); // 읽기시간초과, ms
factory.setConnectTimeout(3000); // 연결시간초과, ms
HttpClient httpClient = HttpClientBuilder.create()
.setMaxConnTotal(100) // connection pool 적용
.setMaxConnPerRoute(5) // connection pool 적용
.build();
factory.setHttpClient(httpClient); // 동기실행에 사용될 HttpClient 세팅
RestTemplate restTemplate = new RestTemplate(factory);
cf) connection pool
미리 connection(연결)을 해놓은 객체들을 pool에 저장해두었다가 클라이언트 요청이 오면 connection을 빌려주고, 처리가 끝나면 다시 connection을 반납받아 pool에 저장하는 방식
RestTemplate 의 동작원리
- 어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
- RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
- RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
- ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
- RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
- ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
- RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
- 어플리케이션에 반환된다.
RestTemplate 를 써보자
1. 생성하기
- 기본 생성
RestTemplate template = new RestTemplate();
2. 주요 메소드
RestTemplate MethodHTTP Method설명
execute | Any | |
exchange | Any | 헤더세팅해서 HTTP Method로 요청보내고 ResponseEntity로 반환받음 |
getForObject | GET | get 요청을 보내고 java object로 매핑받아서 반환받음 |
getForEntity | GET | get 요청을 보내고 ResponseEntity로 반환받음 |
postForLocation | POST | post 요청을 보내고 java.net.URI 로 반환받음 |
postForObject | POST | post 요청을 보내고 ResponseEntity로 반환받음 |
put | PUT | |
delete | DELETE | |
headForHeaders | HEAD | |
optionsForAllow | OPTIONS |
3. Object 로 받기
ForObject 를 사용할때, 응답 xml이나 json 에 맞는 java object(Class responseType)가 필요하다. @XmlElement 를 사용하거나 @JsonProperty 등을 사용하여 매핑해줘야한다.
4. 에러 처리
DefaultResponseErrorHandler를 사용하여 HTTP Error 를 제어한다. restTemplate.setErrorHandler 를 통해 커스텀 핸들러를 등록할 수 있다.
5. 비동기 처리
RestTemplate 는 동기처리에 사용된다. 비동기 처리는 org.springframework.web.client.AsyncRestTemplate 를 사용해야 한다.
그래서 왜 RestTemplate 사용함?
1. API
HttpURLConnection - HTTP와 상호 작용하기 위한 낮은 수준의 API를 제공하여 HTTP 프로토콜의 세부 정보를 수동으로 처리
RestTemplate - Spring Framework의 일부이며 RESTful 서비스를 사용하기 위한 보다 높은 수준의 추상화를 제공. HTTP 요청을 수행하기 위한 보다 편리하고 표현력 있는 API를 제공
2. 사용편의성
RestTemplate - 더 쉽고 간편하게 사용가능
참고