URL_Java

koeyhoyh·2021년 12월 8일
0
post-thumbnail

URLs

학습 내용 :

호스트 상의 자원들에 대한 주소를 어떻게 정하는가?

URL 은 네트워크 상의 자원의 위치를 모호함 없이 찾게 해준다.

URL 클래스를 이용하여 네트워크 상의 데이터를 찾고 가져올 수 있다.

- 프로토콜의 상세사항, 서버와 통신 방법에 관해 염려할 필요가 없고 자바에게 URL 을 전달함으로써 데이터를 얻는다.

URL

  • 자원 자체의 식별 외에 인터넷 상의 자원의 위치를 식별
    - 일반적인 URI 는 어떤 자원인가는 말해주지만 어디서 어떻게 자원을 취하는지는 말하지 않는다.
  • 실제 세계에서 다음 둘은 차이가 있음
    - "Harry Potter and The Deathly Hallows" 라는 이름의 책
    • "Room 312, Row 28, Shelf 7" 라는 서가의 위치
  • Java 에서 다음 둘은 차이가 있음
    - java.net.URI
    • java.net.URL
      • 하나는 자원 식별만 가능, 다른 하나는 식별 + 검색 가능

    URL 의 9가지 구성 요소

  • protocol :// user:password@host:port/path;params?query#fragment
    - protocol://[userID:패스워드@]호스트명[:포트]/경로;파라미터?질의 문자열#분할
    • 주의 : URL 에서는 구분자로 \ 가 아닌 /를 사용함

URL 의 항목

  • Protocol(Scheme)
    - 서버의 자원에 접근하는 방법으로 무슨 프로토콜을 사용할 것인가
    - scheme : URI 의 RFC 에서 사용하는 용어
    - protocol : 자바 문서에서 사용하는 용어

    • 여타 요소와 : 으로 분리됨
    • 예 : file, ftp, http, https, magnet, telnet
  • host
    - 자원을 제공하는 서버 이름

    • 호스트명(예 : www.apple.com) 또는 IP 주소 (예 : 204.148.40.9)
    • 로컬 호스트는 생략할 수 있어서 다음 2가지 형태의 URL이 모두 가능
      • file:///d:/work/file.txt
        • file://localhost/d:/work/file.txt 도 가능
  • 사용자 정보 (User ID 와 Password)
    - 선택사항

  • port
    - Optional

    • 기본 포트 (http 에서는 80) 이면 생략 가능
  • 기관 (Authority)
    - 사용자 정보 (user id:password) + 호스트 + 포트

    • 기관과 호스트의 차이점
      • 기관 = 사용자 정보 + 호스트 + port
      • admin:adminpass@www.blackstar.com:8080
  • 경로
    - 지정된 서버의 특정 자원

    • 파일 시스템에 매핑되기도 하지만 안 되기도 한다.
    • 파일 시스템에 매핑되지 않을 때는 문서 루트에 상대적
      • 파일시스템의 root 에 상대적이지 않음
    • 일반적으로 서버는 일반에게 공개하지만 서버의 전체 파일시스템은 공개하지 않는다.
      • 대신 특정 폴더의 내용만 공개하며 이 특정 폴더를 Document Root 라 한다.
        • 모든 경로와 파일명은 Document Root 에 상대적
    • 생략도 가능함
      • 웹 서버의 경우 index.html, welcome.htm 은 생략 가능
        • http:/index.html 의 경우 host 가 생략되고 바로 path 가 연결된 상태로 http:///index.html 와 동일
  • 파라미터
    - 일부의 Scheme 이 자원에 접근할 때 필요한 부가적인 정보 (가령 ftp에서 자료 전송을 binary 모드로 할 것인가 text 모드로 할 것인가)

    • name/value 쌍으로서 다른 것과 ; 문자로 구분
    • 예 : ftp://prep.ai.mit.edu/pub/gnu;type=d
      • 파라미터 명은 type 이고 값은 d
  • 질의 문자열 (query)
    - http URL 에서만 쓰임

  • 문서 위치 (Fragment Identifier)
    - 자원의 특정 부분을 가리킴

    • HTML 과 같은 타입의 자원일 경우 전체 문서가 더 잘게 쪼개질 수 있음. 쪼개진 조각 하나를 Fragment 라고 함
      • Fragment Identifier = ref = Section = Named Anchor
        • 어떤 곳에서는 Section 이지만 자바에서는 뚜렷한 이유 없이 Ref 사용, XML 문서라면 XPointer 를 가리킴
    • HTML 문서에서 id 속성으로 생성된 분할
    • Comments

    • #를 사용하여 URL

URL 예

단축형 URL

  • URL 은 문서에 관해 웹 브라우저에 알리는 것
    - 문서검색 프로토콜, 문서가 위치한 컴퓨터, 문서까지의 경로

  • 이런 정보의 대부분은 문서에서 참조되는 다른 URL과 일치하기 마련

  • 따라서 전체를 나타내는 것보다 부모 문서 (문서가 들어있는 문서) 의 프로토콜, 호스트, 경로 등을 상속하도록 하는 것이 유리하다.

상대 URL 및 절대 URL

  • 상대 URL (Relative URL)
    - 불완전 URL, 즉 protocol, hostname, path 를 자신이 속한 parent document 로부터 상속 받아야 완전해지는 URL
  • 절대 URL (Absolute URL)
    - 완전한 URL

상대 URL

URL 클래스

  • java.net.URL class
    - URL의 추상화
    - URL (Uniform Resource Locator) - 네트워크 환경에서 정보 위치 표시
    - http://www.hamsterdance.com/ 이나 ftp://ftp.redhat.com/pub 같은 url 의 추상
    • java.lang.Object 를 상속하며 서브 클래싱을 할 수 없는 final class
      • public final class URL extends Object implements Serializable
    • URL 객체는 프로토콜, 호스트 이름, 포트, 경로, 질의 문자열 같은 필드로 구성
    • URL class 의 필드는 생성자를 이용하여 설정
      • Getter 메소드는 있으나 Setter 메소드는 없다.

URL 생성자

  • URL 클래스는 4개의 생성자 제공
  • 자바가 지원하지 않는 프로토콜을 이용하여 URL 객체를 생성할 경우 MalformedURLException 발생
    - 자바 시스템이 지원하는 프로토콜은 자바 버전에 따라 다름.
    • 모든 JVM 에서 지원하는 프로토콜 : HTTP, File
  • URL 객체는 URL 정보를 저장하고 처리할 뿐 유효성 검사를 하지는 않는다.
    - 존재하지 않는 URL 혹은 접속 불가능한 Host 를 URL 객체로 생성 가능

문자열을 이용하여 URL 객체 생성

try{
	URL u = new URL("http://www.jnu.ac.kr");
    }
catch(MalformedURLException e) {
	System.err.println(e);
}

예제 5-1 :

  • JVM 이 지원하는 프로토콜을 검사
    - 14개 프로토콜 문자열을 이용하여 URL 객체 생성
    • URL 객체 생성시 MalformedURLException이 발생하면 JVM 이 지원하지 않는 프로토콜
  • 특이한 점은 JDBC 와 RMI 를 지원하지 않는다는 것
    - JDBC 는 java.sql 에서, RMJ 는 java.rmi 패키지에서 지원한다.
    • 이들은 URL 로 접근할 수 없다.
import java.net.*;

public class ProtocolTester {

  public static void main(String[] args) {
    
    // hypertext transfer protocol
    testProtocol("http://www.adc.org");  
    
    // secure http
    testProtocol("https://www.amazon.com/exec/obidos/order2/"); 
    
    // file transfer protocol
    testProtocol("ftp://ibiblio.org/pub/languages/java/javafaq/");
  
    // Simple Mail Transfer Protocol 
    testProtocol("mailto:elharo@ibiblio.org");

    // telnet 
    testProtocol("telnet://dibner.poly.edu/");
  
    // local file access
    testProtocol("file:///etc/passwd");

    // gopher 
    testProtocol("gopher://gopher.anc.org.za/");
  
    // Lightweight Directory Access Protocol
    testProtocol(
        "ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US?postalAddress");
 
    // JAR
    testProtocol(
        "jar:http://cafeaulait.org/books/javaio/ioexamples/javaio.jar!"
         + "/com/macfaq/io/StreamCopier.class");
  
    // NFS, Network File System
    testProtocol("nfs://utopia.poly.edu/usr/tmp/");
  
    // a custom protocol for JDBC
    testProtocol("jdbc:mysql://luna.ibiblio.org:3306/NEWS");
  
    // rmi, a custom protocol for remote method invocation
    testProtocol("rmi://ibiblio.org/RenderEngine");
  
    // custom protocols for HotJava
    testProtocol("doc:/UsersGuide/release.html");
    testProtocol("netdoc:/UsersGuide/release.html");
    testProtocol("systemresource://www.adc.org/+/index.html");
    testProtocol("verbatim:http://www.adc.org/");
  }
  
  private static void testProtocol(String url) {
    try {  
      URL u = new URL(url);
      System.out.println(u.getProtocol() + " is supported");
    } catch (MalformedURLException ex) {
      String protocol = url.substring(0, url.indexOf(':'));
      System.out.println(protocol + " is not supported");
    }
  } 
}

URL 구성 요소로 URL 객체 생성

  • 프로토콜, 호스트 이름, 파일 이름 3가지 문자열로 URL 객체 생성
    - public URL (String protocol, String hostname, String file) throws MalformedURLException
    • 내부적으로 이 생성자는 포트번호를 -1로 세팅함으로써 프로토콜 별 default port 를 사용하도록 표시한다. (예 : HTTP 는 80 번 포트)
    • file 은 반드시 슬래시(/) 로 시작해야 한다.
      • path + file name
        • 은 파일 내 위치(Named Anchor) 참조

  • Example
try {
	URL u = new URL("http", "www.eff.org", "/blueribbon.html#intro");
    } catch (MalformedURLException e) {
    System.err.println(e);
}

상대 URL 생성자

  • 상대 URL 과 베이스 URL 을 이용하여 절대 URL 객체 생성

  • 이 생성자는 이미 다른 생성자를 통해 만들어진 베이스 URL 에 불완전한 형태의 상대 URL 을 보태 절대 URL 을 만들어 낸다.

  • public URL (URL base, String relative) throws MalformedURLException

예 :

try { 
	URL u1 = new URL("http://metalab.unc.edu/javafaq/index.html");
    URL u2 = new URL(u1, "mailinglist.html");
    } catch (MalformedURLException e) {
    System.err.println(e);
}
  • u1 객체의 경로에서 파일 이름을 빼고 새로운 파일 이름 보충

  • u2는 http://metalab.unc.edu/javafaq/mailinglist.html

  • 사용 예
    - Loop 를 이용하여 어떤 특정 디렉토리 내의 모든 파일을 처리하고자 할 때

    • 애플릿의 getCodeBase(), getDocumentBase() 로부터 얻어진 URL 로부터 상대적인 URL 을 구할 때

주의

상대 URL 예

URL u1 = new URL("http://metalab.unc.edu/javafag/index.html");
URL u2 = new URL(u1, "/mailinglist.html");
System.out.println(u2);
URL u3 = new URL("http://A/B/C/index.html");
URL u4 = new URL(u3, "/mailinglist.html");
System.out.println(u4);
URL u5 = new URL("http://A/B/index.html");
URL u6 = new URL(u5, "A/B/mailinglist.html");
System.out.println(u6);

결과 :

http://metalab.unc.edu/mailinglist.html
http://A/mailinglist.html
http://A/B/A/B/mailinglist.html

참고

URL 객체를 반환하는 메소드들

  • Java.applet.Applet
    - URL getDocumentBase();

    • URL getCodeBase();
  • java.io.File
    - URL toURL()
    - 주어진 파일에 해당하는 URL 리턴
    - Windows 에서 처리하더라도 file:/D:/JAVA/JNP2/07/ToURLTest.java 형태로 \ 가 아닌 /가 사용됨에 유의

  • ClassLoader
    - URL getSystemResource(String name);

    • Enumeration getSystemResources(String name);
    • URL getResource(String name);
  • java.swing.Jeditpane
    - URL getPage();

  • java.net.URLCollection
    - URL getURL();

명령행에서 웹사이트 접근

  • 실행 순서
    - Windows 명령창 실행 (참고 : Windows + R)
    - 실행되지 않으면 다음 처리
    - 시작 -> 제어판 -> 프로그램 및 기능 -> Windows 기능 사용/사용 안함
    - '텔넷 클라이언트' 란을 체크함
      - telnet kr.yahoo.com 80 을 입력한다.
      - GET / 입력하고 엔터를 친다.
      	- 키보드로 입력할 때 입력하는 문자가 보이지 않을 수 있다.
          
      - 해당 웹서버의 HTML 태그가 출력된다.
      
    • 설명
      • 웹서버가 동작하는 80번 포트에 telnet 프로그램을 접속
        • '/' 폴더의 내용을 GET 방식으로 보내달라고 요청 (HTTP 프로토콜에 따른 문자열)
          - 실제로는 / 폴더가 아니라 index.html 문서가 호출된 것이다.

URL 클래스의 메소드

  • URL 클래스는 생성된 URL 객체로부터 데이터를 읽어 오기 위한 4개 메소드를 제공
    - public final InputStream openStream() throws IOException
    • public URLConnection openConnection() throws IOException
    • public final Object getContent() throws IOException
    • public final InputStream getContent(Class[] classes) throws IOException

URL 에서 데이터 가져오기

  • public final InputStream openStream() throws IOException
    - url 에 의해 참조되는 자원에 연결하고 handshaking 하여 자료를 읽을 수 있는 InputStream 을 리턴한다.
    • url 이 가리키는 파일 내용을 있는 그대로 읽어 들이고, HTTP 헤더나 프로토콜 관련 다른 정보를 얻는 것은 포기하는 것을 의미한다.

      • Ascii 이면 Ascii
        • HTML 파일이면 raw HTML 파일을
        • 이미지이면 Binary 를
    • 예제 :

try {
URL u = new URL ("http://www.lolcats.com");
InputStream in = u.openStream();
int c;
while((c = in.read() != -1 ) System.out.write(c);
} catch (IOException e) {
	System.err.println(e);
}
  • 이 메소드는 추상 클래스인 InputStream 객체를 return 한다.
    - 따라서 타입이 불명확하고 InputStream에 정의된 메소드를 사용할 수 있다는 점만 확정된 것이다.
    • 보통 Text를 취급하는 Stream 으로 변환해서 사용할 수도 있지만, 읽어 올 데이터의 실제 타입을 모르고서 byte 스트림으로 가정했다는 모순이 있다.
    • 읽어지는 자료는 raw content (해석되지 않음)

try-with-resource

      InputStream in = null;
      try {
        URL u = new URL(http://www.lolcats.com));
        in = u.openStream();
        int c;
        while ((c = in.read()) != -1)  System.out.write( c);
      } catch (IOException ex) {
        System.err.println(ex);
      } finally {
        if (in != null) {
          try {
            in.close();
          } catch (IOException e) {
            // ignore
          }
        }

try-with-resource

try {
        URL u = new URL(http://www.lolcats.com));
        try (InputStream in = u.openStream()) {
           int c;
           while ((c = in.read()) != -1)  System.out.write( c);
        }
      } catch (IOException ex) {
        System.err.println(ex);
      }

예제 5-2 웹페이지 다운로드

  • 이 프로그램은 다음 2가지를 가정하고 있다.
    - 읽은 파일은 텍스트 파일 형식일 것이다.
    • 내가 사용 중인 시스템과 동일한 인코딩을 사용해서 작성했을 것이다.
  • 참고
    - 웹페이지 다운로드는 TCP socket 프로그래밍으로도 가능하지만 http 프로토콜을 이해해야 한다.
    • URL 클래스를 이용할 때는 http 프로토콜을 몰라도 가능
import java.io.*;
import java.net.*;

public class SourceViewer {

  public static void main (String[] args) {

    if (args.length > 0) {
      InputStream in = null;
      try {
        // Open the URL for reading
        URL u = new URL(args[0]);
        in = u.openStream();
        // buffer the input to increase performance 
        in = new BufferedInputStream(in);       
        // chain the InputStream to a Reader
        Reader r = new InputStreamReader(in);
        int c;
        while ((c = r.read()) != -1) {
          System.out.print((char) c);
        } 
      } catch (MalformedURLException ex) {
        System.err.println(args[0] + " is not a parseable URL");
      } catch (IOException ex) {
        System.err.println(ex);
      } finally {
        if (in != null) {
          try {
            in.close();
          } catch (IOException e) {
            // ignore
          }
        }
      }
    }
  }
} 

실행 결과

  • Eclipse 프로젝트의 Run Configuration에 https://www.jni.ac.kr 을 적고 실행시키면 다음을 얻는다.

<!DOCTYPE html>

<html lang="ko" xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=10.0; user-scalable=1;" /><title>
?????븰援먯뿉 ??떊 寃껋쓣 ?????.
</title><link rel="icon" href="/images/favicon.ico" /><link rel="stylesheet" href="/css/font.css" type="text/css" /><link rel="stylesheet" href="/css/common.css" type="text/css" /><link rel="stylesheet" href="/css/layout.css?v=20190930" type="text/css" /><link rel="stylesheet" href="/css/contents.css" type="text/css" /><link rel="stylesheet" href="/common/js/jquery-ui/themes/smoothness/jquery-ui.min.css" />        
    <script type="text/javascript" src="/Common/js/jquery.min.js"></script>
    <script type="text/javascript" src="/Common/js/jquery.easing.1.3.js"></script>
    <script type="text/javascript" src="/Common/js/jquery-ui/jquery-ui.min.js"></script>
    <script type="text/javascript" src="/Common/js/common.js"></script>       
    <script type="text/javascript" src="/Common/js/common_kr.js"></script>    
    
    <link rel="stylesheet" href="/css/home.css" type="text/css" />
   <link rel="stylesheet" href="/Common/plugin/slick/css/slick.css" type="text/css" />
<link rel="stylesheet" href="/Common/plugin/slick/css/slick-theme.css" type="text/css" />

문제

  • File f = new File ("d:\work\file.txt") 와 URL u = new URL("file:///d:/work/file.txt")의 차이점은?

답 :

  • URL 객체에는 stream 이 연결되어 있다.

문제

  • 로컬 호스트 내 D: 장치의 Work2\JAVA\Test 용 코드 \Network\index.html 파일의 전체 내용을 읽어 내시오

답 :

public class URLDownload {
    public static void main(String args[]) {
        try {
             URL u = new URL("file://localhost/D:/Work2/JAVA/Test용코드/Network/index.html");
             // URL u = new URL("file:///D:/Work2/JAVA/Test용코드/Network/index.html");
             Reader r = new InputStreamReader(new BufferedInputStream(u.openStream()));
             int c;
             while ((c = r.read()) != -1) {
                   System.out.print((char) c);
              }
        } catch (MalformedURLException e) {
               System.err.println(args[0] + " is URL(X)");
        } catch (IOException e) {
               System.err.println(e);
               e.printStackTrace();
       }
    }
}

URL 에서 데이터 가져오기

  • public URLConnection openConnection() throws IOException
    - 이 메소드는 7 장의 주제
    • 지정된 URL 에 대한 Socket 을 열고 URLConnection 객체를 리턴한다.
      • URLConnection 객체를 얻으면 네트워크 상의 리소스에 대한 연결을 얻은 것이며 이것을 이용하여 통신할 수 있다.
        • 읽기 & 쓰기 모두 가능하도록 I/O 각각의 스트림을 얻을 수 있다. 입력의 경우 getInputStream() 을 사용
        • URL에 데이터를 쓰는 것도 가능
          - mailto URL에 메일 발송
          • CGI 에 폼데이타 전송
    • URLConnection 은 서버가 보내는 모든 내용을 전달함
      • 이 메소드는 파일의 내용뿐 아니라 헤더의 내용까지 볼 수 있다.

예제 소스 :

try{
	URL u = new URL("http://www.hamsterdance.com");
    try {
    	URLConnection uc = u.openConnection();
        InputStream in = uc.getInputStream();
        // read from the connection .....
    } catch (IOException e) {
    	System.err.println(e);
    } catch(MalformedURLException e) {
    	System.err.println(e):
}
  • public final Object getContent() throws IOException
    - URL 이 지정하는 데이터의 유형에 따라 2가지 유형을 리턴함
    - ASCII, HTML 등 텍스트 객체일 경우 : InputStream 유형
    - GIF, JPEG 등 이미지 객체일 경우 : java.awt.ImageProducer
    • 서버에서 전달하는 MIME 헤더의 Content-type 필드를 이용하여 객체 타입 결정
    • 이 메소드 호출로 얻어지는 객체가 무슨 타입인지 알아 내야 한다.

Reflection

profile
내가 만들어낸 것들로 세계에 많은 가치를 창출해내고 싶어요.

0개의 댓글