(Http)URLConnection, InputStream & OutputStream

·2023년 7월 27일
0

프로젝트 공부

목록 보기
20/33

URLConnection과 HttpURLConnection

  • URLConnection은 Java 애플리케이션과 URL간의 연결과 관련한 모든 클래스의 수퍼클래스이다.
  • URLConnection 클래스는 일반적인 URL에 대한 api를 제공하고,
    서브클래스 HttpURLConnection는 HTTP고유의 기능에 대한 추가 지원을 제공한다.
  • 두 클래스 모두 추상클래스이다.
  • 따라서 URLConnection및 HttpURLConnection의 새 인스턴스를 직접 만들 수 없다.

URL을 통해 서버와 통신 단계

  1. URL 객체 만들기
  2. URL에서 URLConnection 객체 얻기
  3. URL 연결 구성
  4. 헤더 필드 읽기
  5. 입력 스트림 가져오기 및 데이터 읽기
  6. 출력 스트림 가져오기 및 데이터 쓰기
  7. 연결 닫기

    3~6단계는 선택사항이며, 5~6단계는 바꿔 사용할 수 있다.

1. URL 객체 생성

URL url = new URL("http://www.google.com");

URL 형식이 잘못된 경우 MalformedURLException (IOException의 하위 클래스)을 throw한다

2. URL에서 URLConnection 객체 얻기

URLConnection 인스턴스는 URL 객체의 openConnection() 메소드 호출에 의해 얻어진다.

URLConnection urlConnection = url.openConnection();

프로토콜이 http://인 경우 반환된 객체를 HttpURLConnection 객체로 캐스팅 가능

HttpURLConnection httpUrlConnection = 
				(HttpURLConnection) url.openConnection();

openConnection()실제 네트워크 연결을 설정하지 않고, 단지 인스턴스를 반환한다.
네트워크 연결은 connect() 메서드가 호출될 때 명시적으로 이루어지거나,
헤더 필드를 읽거나 입력스트림/출력스트림을 가져올 때 암시적으로 이루어진다.

3. URL 연결 구성

실제로 연결을 설정하기 전에 타임아웃, 캐시, HTTP 요청 방법 등과 같이 클라이언트와 서버 간의 다양한 옵션을 설정할 수 있다.
아래의 setter 메소드와 같은 이름으로 getter도 있다

URLConnection 클래스가 제공하는 메소드

  • setConnectTimeout (int timeout) : 연결 시간 초과를 밀리초 단위로 설정합니다.(단위 : ms). 연결이 설정되기 전에 제한시간이 만료되면 java.net.SocketTimeoutException이 발생합니다. 시간초과가 0이면, 무한대 타임아웃(기본값)을 의미합니다.

  • setReadTimeout (int timeout) : 읽기 제한 시간을 ms 단위로 설정합니다. 제한 시간이 만료되고 연결의 입력 스트림에서 읽을 수 있는 데이터가 없으면 SocketTimeoutException이 발생합니다. 시간 초과가 0이면 무한대 타임아웃(기본값)을 나타냅니다.

  • setDefaultUseCaches (boolean default) : URLConnection이 기본적으로 캐시를 사용하는지 여부를 설정합니다(기본값은 true). 이 메서드는 URLConnection클래스의 향후 인스턴스에 영향을 줍니다

  • setUseCaches (boolean useCaches) : 이 연결이 캐시를 사용하는지 여부를 설정합니다 (기본값은 true).

  • setDoInput (boolean doInput) : URLConnection을 서버에서 콘텐츠를 읽는 데 사용할 수 있는지 여부를 설정합니다 (기본값은 true).

  • setDoOutput (boolean doOutput) : URLConnection이 서버에 데이터를 보내는 데 사용할 수 있는지 여부를 설정합니다 (기본값은 false).

  • setIfModifiedSince (long time) : 주로 HTTP 프로토콜에 대해 클라이언트가 검색한 콘텐츠의 마지막 수정 시간을 새로설정합니다. 예를 들어, 서버가 지정된 시간 이후에 정적콘텐츠(이미지, HTML)가 변경되지 않았음을 발견하면 콘텐츠를 가져오지 않고 상태 코드 304 - 수정되지 않음을 반환합니다. 클라이언트는 지정된 시간보다 최근에 수정된 경우 새로운 콘텐츠를 받게 됩니다.

  • setAllowUserInteraction (boolean allow) : 사용자 상호 작용을 활성화 또는 비활성화합니다. 예를 들어 필요한 경우 인증 대화 상자를 표시합니다(기본값은 false).

  • setDefaultAllowUserInteraction (부울 기본값) : 이후의 모든 URLConnection객체에 대한 사용자 상호 작용의 기본값을 설정

  • setRequestProperty (String key, String value) : key=value 쌍으로 지정된 일반 요청 속성을 설정합니다. 키가 있는 속성이 이미 있는 경우 이전 값을 새 값으로 덮어씁니다.
    이러한 메서드는 연결을 설정하기 전에 호출해야 합니다. 일부 메서드 는 연결이 이미 설정된 경우 IllegalStateException을 발생시킵니다.또한 하위 클래스 HttpURLConnection 은 HTTP 관련 기능을 사용하여 연결을 구성하기 위한 다음 메서드를 제공합니다.

  • setRequestMethod (String method) : HTTP 메소드 GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE 중 하나인 URL 요청에 대한 메소드를 설정합니다. 기본 방법은 GET입니다.

  • setChunkedStreamingMode (int chunkLength) : 콘텐츠 길이를 미리 알 수 없는 경우 내부 버퍼링 없이 HTTP 요청 본문을 스트리밍할 수 있습니다.

  • setFixedLengthStreamingMode (long contentLength) : 콘텐츠 길이를 미리 알고 있는 경우 내부 버퍼링 없이 HTTP 요청 본문을 스트리밍할 수 있습니다.

  • setFollowRedirects (boolean follow) : 이 정적 메서드는 HTTP 리디렉션 뒤에 이 클래스의 향후 개체가 자동으로 따라야 하는지 여부를 설정합니다(기본값은 true).

  • setInstanceFollowRedirects (boolean follow) : HTTP 리디렉션 다음에 이HttpURLConnection클래스의 인스턴스가 자동으로 따라와야 하는지 여부를 설정합니다(기본값은 true).

4. 헤더 필드 읽기

연결이 이루어질 때 서버는 URL 요청을 처리하고 메타데이터와 실제 콘텐츠로 구성된 응답을 다시 보낸다. 메타데이터는 헤더 필드라고 하는 키=값 쌍의 모음이다.
헤더필드는 서버에 대한 정보, 상태 코드, 프로토콜 정보 등을 나타낸다. 실제 내용은 문서의 유형에 따라 텍스트, HTML, 이미지 등이 될 수 있다.

URLConnection클래스가 헤더 필드를 읽기 위해 제공하는 메서드

  • getHeaderFields () : 모든 헤더 필드를 포함하는 맵을 반환합니다. 키는 필드 이름이고 값은 해당 필드 값을 나타내는 문자열 목록입니다.

  • getHeaderField (int n) : n 번째 헤더 필드의 값을 읽습니다.

  • getHeaderField (String name) : 명명된 헤더 필드의 값을 읽습니다.

  • getHeaderFieldKey (int n) : n 번째 헤더 필드의 키를 읽습니다.

  • getHeaderFieldDate (String name, long default) :Date. 필드가 없거나 값 형식이 잘못된 경우 기본값이 대신 반환됩니다.

  • getHeaderFieldInt (String name, int default) : 정수로 구문 분석된 명명된 필드의 값을 읽습니다. 필드가 없거나 값 형식이 잘못된 경우 기본값이 대신 반환됩니다.

  • getHeaderFieldLong (String name, long default) : 긴 숫자로 구문 분석된 명명된 필드의 값을 읽습니다. 필드가 없거나 값 형식이 잘못된 경우 기본값이 대신 반환됩니다.
    헤더 필드를 읽는 일반적인 방법입니다. 그리고 자주 액세스하는 일부 헤더 필드의 경우 URLConnection 클래스는 보다 구체적인 메서드를 제공합니다.

  • getContentEncoding () : 콘텐츠의 인코딩 유형을 나타내는 콘텐츠 인코딩 헤더 필드의 값을 읽습니다.

  • getContentLength () : 콘텐츠의 크기(바이트)를 나타내는 콘텐츠 길이 헤더 필드의 값을 읽습니다.

  • getContentType () : 컨텐츠의 유형을 나타내는 컨텐츠 유형 헤더 필드의 값을 읽습니다.

  • getDate () : 서버의 날짜 시간을 나타내는 날짜 헤더 필드의 값을 읽는다.

  • getExpiration () : 만료 헤더 필드의 값을 읽고 응답이 오래된 것으로 간주되는 시간을 나타냅니다. 이것은 캐시 제어를 위한 것입니다.

  • getLastModified () : 컨텐츠의 마지막 수정 시간을 나타내는 last-modified 헤더 필드의 값을 읽는다.
    그리고 하위 클래스 HttpURLConnection 은 추가 메서드를 제공합니다.

  • getResponseCode () : 서버에서 보낸 HTTP 상태 코드를 반환합니다.
    헤더 필드를 읽을 때 connect() 를 호출하지 않고 암시적으로 연결이 설정 됩니다.

  • getResponseMessage () : 응답 메세지를 반환합니다

5. 입력 스트림 가져오기 및 데이터 읽기

실제 내용을 읽으려면 연결에서 InputStream 인스턴스를 얻은 다음
InputStreamread() 메서드를 사용하여 데이터를 읽어야 합니다.

InputStream inputStream = urlCon.getInputStream();
byte[] data = new byte[1024];
inputStream.read(data);

InputStream 의 read() 는 데이터 를 바이트 배열로 읽는 저수준 메서드입니다. 따라서 데이터를 문자로 읽기 위해 InputStreamReader 에서 InputStream 을 래핑하는 것이 더 편리합니다 .

InputStream inputStream = urlCon.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
 
int character = reader.read();  // reads a single character
char[] buffer = new char[4096];
reader.read(buffer);    // reads to an array of characters

또는 데이터를 문자열로 읽기 위해 InputStream 을 BufferedReader 로 래핑합니다 .

BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = reader.readLine(); // reads a line

getInputStream() 메서드에서 발생 가능한 예외

  • IOException : 입력 스트림을 생성하는 동안 I/O 오류가 발생한 경우.
  • SocketTimeoutException : 데이터를 읽을 수 있기 전에 읽기 제한 시간이 만료되는 경우.
  • UnknownServiceExcepetion : 프로토콜이 입력을 지원하지 않는 경우.

6. 출력 스트림 가져오기 및 데이터 쓰기

서버에 데이터를 보내려면 먼저 연결에서 출력을 활성화해야 합니다.

urlCon.setDoOutput(true);

연결과 연결된 OutputStream 객체를 가져온 다음 OutputStreamwrite() 메서드를 사용하여 데이터를 씁니다.

OutputStream outputStream = urlCon.getOutputStream();
byte[] data = new byte[1024];
outputStream.write(data);

OutputStream 의 write () 는 바이트 배열을 쓰는 저수준 메서드입니다. 따라서 문자를 쓰기 위해 OutputStreamWriter 에서 OutputStream 을 래핑하는 것이 더 편리합니다 .

OutputStreamWriter writer = new OutputStreamWriter(outputStream);
int character = 'a';
writer.write(character); // writes a single character
 
char[] buffer = new char[4096];
writer.write(buffer); // writes an array of characters

또는 문자열을 작성하기 위해 PrintWriter 에서 OutputStream 을 래핑합니다.

PrintWriter writer = new PrintWriter(outputStream);
String line = "This is String";
writer.print(line);

getOutputStream() 메서드에서 발생 가능한 예외

  • IOException
  • UnknownServiceException

7. 연결 닫기

연결을 닫으려면 InputStream 또는 OutputStream 객체 에서 close()메서드를 호출

InputStream & OutputStream

바이트 기반 스트림, 문자 기반 스트림

  • 바이트 기반 스트림

    • 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 받고 보내는 것이 가능
    • 사람은 읽지 못한다. 문자가 깨져서 보이게 됨
  • 문자 기반 스트림

    • 문자만 받고 보낼 수 있도록 특화
    • 사람이 읽을 수 있음

InputStream

InputStream = 바이트 기반 입력 스트림의 최상위 클래스, 추상클래스

InputStream의 주요 메서드

리턴타입메소드설명
intread()입력 스트림으로부터 1바이트를 읽고 읽은 바이트를 return
intread(byte[] b)입력 스트림으로부터 읽은 바이트들을 매개값으로 주어진 바이트 배열 b에 저장하고 실제로 읽은 바이트 수를 return
intread(byte[] b, int off, int len)입력 스트림으로부터 len개의 바이트만큼 읽고 매개값으로 주어진 바이트 배열 b[off]로부터 len개까지 저장한다. 그리고 실제로 읽은 바이트 수인 len개를 return. 만약 len개를 모두 읽지 못하면 실제로 읽은 바이트 수를 return
voidclose()사용한 시스템 자원을 반납하고 입력 스트림을 닫는다.

OutputStream

OutputStream의 주요 메서드

리턴타입메소드설명
voidwrite()출력 스트림으로부터 1바이트를 보낸다.
voidwrite(byte[] b)출력 스트림에 매개값으로 주어진 바이트 배열 b의 모든 바이트를 보낸다.
voidwrite(byte[] b, int off, int len)출력 스트림에 매개값으로 주어진 바이트 배열 b[off]로부터 len개까지의 바이트를 보낸다.
voidflush()버퍼에 잔류하는 모든 바이트를 출력한다.
voidclose()사용한 시스템 자원을 반납하고 입력 스트림을 닫는다.

참고
Java URLConnection 및 HttpURLConnection 사용 방법
https://blog.naver.com/ggwabaegiii/223051471062

profile
개발자가 되고싶은 낭랑 24세

0개의 댓글

관련 채용 정보