[Java Network] 3. URLConnection


URL Connection은 Java에서 제공하는 네트워크 API로 특정 URL과의 연결을 설정하고 데이터를 주고받을 수 있도록 해준다. 이 API는 다양한 프로토콜(HTTP, HTTPS, FTP 등)을 통해 데이터를 송수신할 수 있으며, 네트워크 통신을 위한 기본적인 기능을 제공한다. URL과 URL Connection의 관계 URL는 특정 리소스를 가리키는 주소를 나타내는 객체이고 URLConnection은 URL에 연결하고 데이터를 주고받기 위한 클래스이다.



1. URL (Uniform Resource Locator)

URL은 웹 상의 특정 자원을 가리키는 표준화된 주소 체계로 인터넷에서 파일, 웹 페이지, 이미지, API, 데이터베이스 등에 접근하기 위해 사용된다. 인터넷 상의 “주소표” 역할을 한다.



2. URL의 구조

프로토콜://도메인[:포트]/경로[?쿼리문자열][#프래그먼트]
  1. 프로토콜 (Protocol):
    • 리소스에 접근하기 위해 사용하는 통신 규약
    • 예: http, https, ftp, file
    • https://: 보안이 강화된 HTTP 프로토콜
  2. 도메인 (Domain):
    • 인터넷 상의 서버를 식별하는 고유한 이름
    • 예: example.com, google.com
  3. 포트 번호 (Port):
    • 서버에서 사용하는 네트워크 포트 번호
    • 기본적으로 생략 가능 (HTTP는 80, HTTPS는 443 사용)
    • 예: :8080 (웹 서버의 특정 포트를 지정할 때 사용)
  4. 경로 (Path):
    • 서버 내에서 자원이 위치한 디렉터리 경로
    • 예: /products/list
  5. 쿼리 문자열 (Query String):
    • 요청에 추가 정보를 전달하기 위해 사용하는 키-값 쌍
    • ?로 시작하며, &로 여러 값을 구분
    • 예: ?id=123&name=John
  6. 프래그먼트 (Fragment):
    • 문서 내 특정 섹션을 가리키는 부분
    • 예: #section2 (웹 페이지의 특정 부분으로 이동)



3. URL 객체

URL 클래스의 주요 메서드

메서드설명
URL(String spec)URL 객체를 생성
URL(String protocol, String host, int port, String file)URL 객체를 구성 요소별로 생성
getProtocol()URL의 프로토콜을 반환 (http, https, ftp 등)
getHost()URL의 호스트 이름을 반환
getPort()URL의 포트 번호를 반환 (포트가 지정되지 않은 경우 -1 반환)
getDefaultPort()프로토콜의 기본 포트 번호를 반환
getFile()URL의 파일 경로를 반환
getPath()URL의 경로 부분만 반환
getQuery()URL의 쿼리 문자열을 반환
getRef()URL의 프래그먼트(앵커)를 반환 (# 뒤의 부분)
getUserInfo()URL의 사용자 정보를 반환
toExternalForm()URL을 문자열로 반환 (URL 객체를 완전한 문자열로 표현)
toString()URL을 문자열로 반환 (보통 toExternalForm()과 동일)
equals(Object obj)URL 객체가 같은 리소스를 가리키는지 비교
hashCode()URL 객체의 해시 코드를 반환
openConnection()URL에 대한 연결 객체(URLConnection)를 반환
openStream()URL의 입력 스트림을 열어 데이터를 읽음
getAuthority()URL의 권한 정보를 반환 (host:port 형식)
sameFile(URL other)두 URL이 동일한 파일을 가리키는지 비교
getContent()URL에서 데이터를 가져와 객체로 반환
getContent(Class[] classes)특정 클래스 형식으로 URL 콘텐츠를 가져옴



4. URLConnection 클래스

URL과 URL Connection의 관계

  • URL: 특정 리소스를 가리키는 주소를 나타내는 객체
  • URLConnection: URL에 연결하고 데이터를 주고받기 위한 클래스.


4-1. URLConnection의 주요 기능

  1. URL 연결:
    • URL 객체를 통해 서버와 연결을 설정
  2. 요청 설정:
    • HTTP 헤더를 통해 서버에 필요한 정보를 전달
  3. 데이터 송수신:
    • 입력 스트림(InputStream)과 출력 스트림(OutputStream)을 사용하여 데이터 송수신
  4. 타임아웃 설정:
    • 연결 및 읽기 작업에서의 최대 대기 시간을 설정
  5. 헤더 관리:
    • 요청 및 응답 헤더의 정보를 읽거나 설정


4-2. URLConnection 클래스의 주요 메서드

연결 및 초기화

| 메서드 | 설명 | |——————————————-|———————————————————————————————| | connect() | URL에 실제로 연결을 수행 | | setConnectTimeout(int timeout) | 연결 타임아웃(밀리초)을 설정 | | setReadTimeout(int timeout) | 읽기 타임아웃(밀리초)을 설정 | | getConnectTimeout() | 설정된 연결 타임아웃 값을 반환 | | getReadTimeout() | 설정된 읽기 타임아웃 값을 반환 |

데이터 송수신

| 메서드 | 설명 | |——————————————-|———————————————————————————————| | getInputStream() | 입력 스트림을 반환하여 서버의 응답 데이터를 읽음 | | getOutputStream() | 출력 스트림을 반환하여 서버에 데이터를 보냄 | | setDoInput(boolean doInput) | 입력 스트림을 사용할지 여부를 설정 (기본값: true) | | setDoOutput(boolean doOutput) | 출력 스트림을 사용할지 여부를 설정 |

헤더 관리

| 메서드 | 설명 | |——————————————-|———————————————————————————————| | setRequestProperty(String key, String value) | 요청 헤더에 특정 키와 값을 설정 | | getRequestProperty(String key) | 요청 헤더의 값을 반환 | | getHeaderField(String name) | 응답 헤더의 특정 값을 반환 | | getHeaderFields() | 응답 헤더의 모든 값을 Map으로 반환 | | getContentLength() | 응답 데이터의 길이를 반환 (바이트 단위) | | getContentType() | 응답의 콘텐츠 타입을 반환 | | getContentEncoding() | 응답 콘텐츠의 인코딩 방식을 반환 | | getLastModified() | 응답 데이터의 마지막 수정 시간을 반환 |

기타

| 메서드 | 설명 | |——————————————-|———————————————————————————————| | getContent() | 응답 데이터를 Object 형태로 반환 | | getPermission() | URLConnection에 필요한 권한을 반환 | | getURL() | URL 객체를 반환 |


4-3. HttpURLConnection 예제코드

public class URLConnectionExample {
    public static void main(String[] args) {
        try {
            // 네이버 URL 설정
            URL url = new URL("https://www.naver.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 요청 메서드 및 타임아웃 설정
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000); // 연결 타임아웃: 5초
            connection.setReadTimeout(5000);    // 읽기 타임아웃: 5초

            // 요청 헤더 설정
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

            // 서버로부터 응답 코드 받기
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            // 응답 헤더 출력
            Map<String, List<String>> headers = connection.getHeaderFields();
            System.out.println("\nResponse Headers:");
            for (Map.Entry<String, List<String>> header : headers.entrySet()) {
                System.out.println(header.getKey() + ": " + String.join(", ", header.getValue()));
            }

            // 응답 본문 읽기
            if (responseCode == HttpURLConnection.HTTP_OK) { // HTTP 200인 경우만 출력
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                System.out.println("\nResponse Body:");
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
                reader.close();
            } else {
                System.out.println("Failed to fetch content. HTTP Response Code: " + responseCode);
            }

            // 연결 해제
            connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}