프로젝트를 진행하면서 Java 로 youtube data api 를 활용하여 데이터를 조회해야 하는 작업이 생겨서 조사해보았다.
1. HTTP 통신 개념
HTTP(Hyper Text Transfer Protocol)는 웹을 이용하기 위해 필요한 통신규약으로, 웹 서버가 실행하는 서비스를 요청하고 받기 위해 사용된다.
클라이언트에서 웹 서버로 요청하고 응답을 받기 위해 사용된다. 이 규약은 클라이언트가 데이터를 서버로 전송하고, 서버는 클라이언트로 다시 데이터를 전송하기 위해 필요하다.
2. Java 에서 HTTP 통신 사용 방법
Java 에서 HTTP 통신을 사용하기 위해서는 다양한 오픈소스 라이브러리를 사용할 수 있다.
Apache HttpClient, Unirest, Rest-assured 등이 있다. 각 라이브러리는 간단한 메소드를 통해 HTTP 메서드를 사용할 수 있게 해준다.
또한, Java 의 URLConnection 클래스를 사용하여 HTTP 통신을 수행할 수도 있다.
3. Java Http 통신 라이브러리
Java 는 HTTP 통신을 하기 위해 여러 라이브러리를 제공한다. 가장 많이 사용하는 라이브러리는 HttpURLConnection, HttpClient, ApacheHttpClient, OkHttp 가 있다.
3-1. HttpURLConnection - 표준 라이브러리
- 장점
- 자바에서 제공하는 표준 라이브러리
- 때문에 외부 종속성이 필요하지 않다는 큰 장점
- 상대적으로 사용하기 쉽고 요청할 수 있는 유형과 설정할 수 있는 옵션측에서 많은 유연성 제공
- 단점
- 복잡한 Request/Response 에 대한 처리가 불편
- 서버의 Response 를 별도의 객체로 받아서 처리하지 못하기 때문에 while 문을 통해 readLine 메서드로 일일히 받은 후 처리해야 한다.
- 자동 재시도 또는 연결 풀링 같은 기능을 지원하지 않으므로 원하면 직접 처리해야 한다.
3-2. HttpClient
- java.net.http.HttpClient 는 Java 11 에 도입된 새로운 HTTP 클라이언트이다.
- HTTP/2 및 WebSocket 을 지원한다.
- HttpURLConnection은 비동기 처리를 위해 별도의 과정이 필요했는데, HttpClient는 별도의 과정 없이 비동기 처리 기능을 제공한다.
3-3. Apache HttpClient - 외부 라이브러리
- 장점
- 다양한 기능 및 커스터마이즈 옵션을 제공
- 다양한 HTTP 메서드 및 프로토콜 지원
- 단점
- 다른 라이브러리보다 더 많은 리소스를 사용하고 느림
- 설치 공간이 더 클 수 있고 더 많은 설정이 필요
- 현재 안드로이드에서는 Deprecated 되었다고 함
3-4. OkHttp
- 장점
- 안드로이드에서도 사용가능
- 설치 공간이 작다.
- 서버당 단일 연결을 사용하고 자동으로 연결을 재사용하여 연결 생성 및 해제의 오버헤드를 줄였다.
- HTTP/2 및 WebSocket을 지원
- 단점
- 다른 라이브러리보다 더 많은 리소스를 사용하고 느리다.
- 가벼운 HTTP 통신에는 적합하지 않을 수 있음
난 이 라이브러리 중 HttpURLConnection 를 선택하여 사용하기로 했다.
👩⚖️👩⚖️👩⚖️
더 자세히 알아보자!
4. Java API 활용
Java.net 패키지에는 네트워크 애플리케이션을 구현하기 위한 클래스들이 있다.
이 패키지에 있는 HttpUrlConnection 클래스와 URL 클래스를 활용해서 HTTP 통신을 할 수 있다.
4-1. URL 클래스
URL 클래스는 자원을 요청할 주소를 나타내는 클래스이다.
URL클래스를 보면 Serializable 인터페이스를 구현하고 있어서, 직렬화를 위한 조건을 갖추고 있다.
public final class URL implements java.io.Serializable { ... }
4-1-1. URL 객체 생성하기
URL 클래스의 생성자는 다양한 형태로 선언되어 있다.
그 중에 가장 많이 이용되는 생성자는 url 을 문자열 형태로 나타낸 객체의 레퍼런스를 인자로 전달받는 생성자이다.
public URL(String spec) throws MalformedURLException { ... }
예제
https://www.naver.com 의 url 을 나타내는 URL 객체를 생성하고 싶다면 다음처럼 코드를 작성하자
import java.net.URL;
...
URL url = new URL("<https://www.naver.com>");
🖐️ 여기서 잠깐!
공식 Java API 문서를 보면, 위에서 사용한 생성자를 비롯해 모든 URL 클래스 객체의 생성자는 MalformedURLException ****예외를 throws 하여 예외처리에 대한 책임을 전가하고 있다. MalformedURLException은 생성자의 인자로 받은 url 문자열이 null이거나 프로토콜을 알 수 없을 때 등의 상황에 발생한다.
⇒ 따라서 URL 객체를 생성한 클래스에서 그 예외를 처리해주어야 한다.
try {
URL url = new URL("<https://www.naver.com>");
} catch (MalformedURLException e) {
e.printStackTrace();
}
4-1-2. 연결 객체 얻기
URL 클래스에 선언된 openConnection() 메서드는 url 객체에 대한 연결을 담당하는 URLConnection 객체를 반환한다.
transient URLStreamHandler handler;
...
public URLConnection openConnection() throws java.io.IOException {
return handler.openConnection(this);
}
예제
위에서 생성한 URL 객체에 대한 연결 객체를 얻어보자!
URLConnection connection = url.openConnection();
4-2. HttpURLConnection 클래스
HttpURLConnection 클래스는 HTTP 프로토콜 통신을 위한 클래스이다.
각각의 객체들은 하나의 요청을 위해 사용된다.
이 클래스를 살펴보면 URLConnection 클래스를 확장한(상속받은) 추상클래스임을 알 수 있다.
public abstract class HttpURLConnection extends URLConnection { ... }
4-2-1. HttpURLConnection 객체 생성
위에서 URL 객체의 openConnection() 메소드를 통해 URLConnection 객체를 얻을 수 있었다. HttpURLConnection객체는 URLConnection 객체를 확장하고(상속받고)있기 때문에 Type Casting을 통해 HttpURLConnection객체를 쉽게 얻을 수 있다.
예제
https://www.naver.com 의 url 을 나타내는 URL 객체를 생성하고 싶다면 다음처럼 코드를 작성하자
(예외처리 생략)
import java.net.URL;
import java.net.HttpURLConnection;
...
URL url = new URL("<https://www.naver.com>");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
4-2-2. 요청 메서드 설정
HTTP 요청을 위해서는 요청 메소드를 설정해야 한다.
setRequestMethod() 메소드는 요청 메소드를 문자열 파라미터로 받아서 유효한 요청 메소드면 method 멤버 변수에 요청 메소드를 저장하고, 아니면 ProtocolException 예외를 발생시킨다.
처리할 수 있는 요청 메소드로는 GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE 가 있다.
public void setRequestMethod(String method) throws ProtocolException {
...
}
method 멤버변수는 기본으로 "GET"으로 초기화되어있다.
따라서 setRequestMethod()를 통해 요청 메소드를 설정하지 않으면 GET 요청을 보내게 된다.
protected String method = "GET";
예제
위에서 생성한 HttpURLConnection 객체로 GET, POST 요청을 하고 싶다면 다음과 같이 코드를 작성하자
connection.setRequestMethod("GET");
connection.setRequestMethod("POST");
4-2-3. 요청 헤더 설정
HttpURLConnection 클래스가 확장(상속)하는 URLConnection클래스에 정의된 setRequestProperty() 메소드로 요청헤더를 설정할 수 있다.
setRequestProperty() 메소드는 String 타입의 key, value 파라미터를 받는다.
각 파라미터를 통해 요청 헤더의 이름과 값을 설정할 수 있다.
만약 key값이 null이라면 NullPointerException 예외를 발생시킨다.
public void setRequestProperty(String key, String value) {
checkConnected();
if (key == null){
throw new NullPointerException ("key is null");
}
if (requests == null){
requests = new MessageHeader();
}
requests.set(key, value);
}
4-2-4. 서버와의 연결제한 시간
con.setConnectTimeOut(1000);
- 밀리 세컨드 단위로 설정
- 타임 아웃시, java.net.SocketTimeoutException 발생
- 타임아웃이 0이면 무한 타임아웃으로 해석
4-2-5. 서버와의 연결 후 데이터를 읽는 시간
con.setReadTimeOut(1000);
- 밀리 세컨드 단위로 설정
- 0이 아닌 값은 입력스트림에서 읽을 때 초과하는 시간을 지정
- 타임 아웃시, java.net.SocketTimeoutException 발생
- 타임아웃이 0이면 무한 타임아웃으로 해석
📝 Connect Time Out 과 Read Time Out은URL 호출 시 무한대기 상태를 방지하기 위함으로 작성된다고 함
이 내용을 잘 활용하여 youtube data api 를 조회후 원하는 정보를 얻어보겠다!
참고 블로그
[Java] Java로 HTTP GET, POST 통신하기
Java에서 HTTP 통신의 개념과 사용 방법 - 자바림
'자바' 카테고리의 다른 글
[JAVA] Vector 클래스 (0) | 2023.08.18 |
---|---|
[JAVA] 문자열 상수 풀(String Constant Pool) (0) | 2023.08.16 |
[JAVA] Equals() (0) | 2023.08.16 |
[Java] HashMap (0) | 2023.03.27 |
[Java] HashSet (1) | 2023.03.15 |