REST 간단 설명
REST란 네트워크 상의 자원에 접근하는 방식을 정해놓은 규칙으로, 쉽게 이해 가능하고 HTTP 프로토콜의 인프라를 그대로 사용하므로 범용성까지 보장되는 데이터 전달 방식이다.
REST는 HTTP URI를 통해 자원을 명시하고 HTTP 메서드를 통해 자원에 대한 행위 표현 및 자원에 대한 연산을 처리하는 방식으로 진행된다.
REST의 원리를 그대로 따르는 API를 REST API라고 하며, API의 모습에서 요청이 어떤 동작이나 정보를 위한 것인지 추론할 수 있다.
HttpURLConnection
HttpURLConnection을 이용하면 자바 프로그램 내에서 REST 통신이 가능하다(즉 REST API 이용 가능).
HttpURLConnection의 생성자는 protected이므로 코드 내에서 직접 객체를 생성할 수는 없고, 객체를 얻기 위해서는 통신하고자 하는 리소스를 가리키는 URL 객체가 필요하다.
URL 객체의 openConnection()이 반환하는 객체는 URLConnection을 구현한 객체이다.
하지만, URL 객체가 가리키는 url이 HTTP(또는 HTTPS) 프로토콜을 사용한다면, openConnection()이 반환하는 객체를 HttpURLConnection으로 다운캐스팅하여 사용할 수 있다.
// 구글 사이트와의 연결을 의미하는 HttpURLConnection 객체 획득 과정
URL url = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
HttpURLConnection의 대표 메서드
HttpURLConnection에는 REST 통신을 위한 다양한 메서드가 정의되어 있지만, 아래의 메서드 정도만 알아도 기본적인 통신이 가능하다.
요청 전송 전~직전 과정에서 실행하는 메서드
- void setConnectTimeout(int timeout)
- 밀리초 단위로 리소스(서버)와의 연결시간 설정
- 연결이 확립되기 전에 timeout이 만료되면 SocketTimeoutException 발생
- timeout의 기본값은 0이며, 무한대를 의미(만료시간 비활성화 의미)
- void setReadTimeout(int timeout)
- 밀리초 단위로 InputStream으로부터 데이터를 읽는 제한 시간을 설정
- timeout이 만료되었음에도 내부 InputStream으로부터 데이터를 읽지 못한 경우 SocketTimeoutException 발생
- timeout의 기본값은 0이며, 무한대를 의미(만료시간 비활성화 의미)
- void setDoInput(boolean doinput)
- 클래스 내 doInput 필드의 값을 설정함으로써, 연결을 통해 리소스부터 데이터를 읽을지 여부를 선택
- doInput 필드의 기본값은 true
- void setDoOutput(boolean dooutput)
- 클래스 내 doOutput 필드의 값을 설정함으로써, 연결을 통해 리소스로 데이터를 보낼지 여부를 선택
- doOutput 필드의 기본값은 false
- POST 방식으로 요청할 때 데이터를 url로 보내기 위해 true로 설정해야 함
- void setRequestMethod(String method)
- http 요청에 사용할 http 메서드를 설정
- GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE 중에서 설정 가능
- 기본값은 GET
- http 요청에 사용할 http 메서드를 설정
- void setRequestProperty(String key, String value)
- 키=값 형태의 요청 프로퍼티를 설정
- http의 경우 요청 헤더를 설정하는 역할
- void connect() throws IOException
- HttpURLConnection과 관련된 url에 실제로 요청을 진행
- connect()가 실행되기 전에 옵션을 미리 설정해야 함(위에 적어둔 보라색 메서드. http 메서드, 연결시간 등)
요청 전송 후 실행하는 메서드
헤더 필드를 읽거나 입출력 스트림을 얻는 메서드를 실행하면 암묵적으로 connect()가 실행됨
- int getResponseCode()
- HTTP 응답 메시지의 상태 코드 번호를 리턴
- 상태 코드 번호에 해당하는 상수 필드가 정의되어 있어 비교할 때 유용
- 예: HttpURLConnection.HTTP_OK는 200을 뜻함
- InputStream getInputStream() throws IOException
- 객체 자신의 연결과 관련된 InputStream을 리턴
- 요청이 끝난 후 InputStream 객체의 close()를 실행하면 자신과 관련된 네트워크 리소스와의 연결까지 해제함
- OutputStream getOutputStream() throws IOException
- 연결을 통해 리소스로 데이터를 보낼 OutputStream을 리턴
- 요청이 끝난 후 OutputStream 객체의 close()를 실행하면 자신과 관련된 네트워크 리소스와의 연결까지 해제함
- void disconnect()
- 네트워크 리소스와의 연결을 해제함
- 스트림의 close()와의 차이점은 connect()를 실행하면 다시 요청 진행가능하다는 정도
예시 코드
더미 json을 응답해주는 jsonplaceholer.typicode.com에 요청을 보낸 후, 응답을 콘솔창에 출력하는 간단한 프로그램이다.
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
URL url = new URL("https://jsonplaceholder.typicode.com/posts/1");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(1000);
connection.setRequestMethod("GET");
String res = "";
StringBuilder sb = new StringBuilder();
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String data;
while((data = br.readLine()) != null) {
sb.append(data);
}
is.close();
}
System.out.println(sb.toString());
}
}
코드 실행시 콘솔창에 출력되는 문자열은 아래와 같다.
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
참고한 글들
https://velog.io/@yyy96/REST-API
https://serverrefository.tistory.com/64
https://infos.tistory.com/4640
https://blueyikim.tistory.com/2199
https://logging-panda.tistory.com/63
https://www.codejava.net/java-se/networking/how-to-use-java-urlconnection-and-httpurlconnection
'백엔드 공부 메모 > JAVA' 카테고리의 다른 글
열거체, enum 클래스 (0) | 2024.04.27 |
---|---|
Lombok 사용법 간단정리 (0) | 2024.03.20 |