728x90
반응형

URL Class

  • java.net.URL을 사용한다
  • Final Class이므로 상속이 되지 않는다
  • Immutable 하므로 fields는 생성된 이후에 바꿀 수 없다
  • fields에는 protocol, host, path 등이 있다.
  • 생성자가 존재한다. 생성자로 새로운 URL을 만든다
    • public URL(String url) throws MalformedURLException → 지원되지 않는 protocol이나 URL 문법에 맞지 않으면 MalformedURLException에 속한다
    • public URL(String protocol, String host, int port, String file) throws MalformedURLException
  • 생성자는 생성된 URL이 유효한지 안한지 체크하지 않는다. 그래서 URL이 존재하지 않거나 존재하더라도 접속되지 않을 수도 있다.
  • URL syntax가 만족해야 하는 것은 일단 ‘:’ 가 있어야 한다. 세미콜론을 통해 schem이나 protocol을 구분한다. 뒤에 오는 것은 어떤지는 신경쓰지 않는다.

URL로 데이터를 얻는 방법

  • data를 얻는 함수를 알아보겠다
  • public InputStream openStream() throws IOException
    • 제일 많이 사용되고 기본이 된다.
    • Client와 Server의 handshaking도 실행한다
    • 읽어들일 수 있는 data에서 InputStream을 반환한다.
    • InputStream으로 읽는 data는 raw content이다. 즉, ASCII 텍스트 파일은 ASCII로 읽히고, image file은 binary image data로 읽힌다.
    • HTTP header나 protocol 관련 정보는 포함하지 않는다.
    • 한계 : 너무 상위 레벨이라서 생기는 한계가 있다.
      • openStream()은 URL이 text를 가리키고 있다고 가정한다. 그러나 실제로 URL은 image나 sound, video같은 다른 타입도 가리킬 수 있다.
      • text이더라도 server에서의 encoding과 receiver에서의 encoding이 다를 수도 있다.
      • 다른 OS이면 해석이 다를 수도 있다.
      • HTTP header도 encoding 정보가 있을 수 있는데 여기서는 위에 말한대로 HTTP header를 읽을 수 없다.
      • 그래서 openConnection()이 필요하다.
    // 인수로 url 아무거나 넣어서 테스트하면 된다.
    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){}
                    }
                }
            }
        }
    }
    
  • public URLConnection openConnection() throws IOException
    • 반환 객체로부터 InputStream을 얻어야 할 수 있다
    • openStream보다 low level control이다.
    • openStream은 openConnection과 getContent()을 동시에 하는 것이다.
  • public Object getContent() throws IOException
    • 어떤 type으로 data retrieve 할것인지 결정할 수 있다.
      • URL은 ASCII나 HTML file을 의미할 수 있다.
      • URL은 GIF나 JPEG같은 image를 의미할 수 있다. → java.awt.ImageProducer가 return된다.
    • header of data에 있는 Content type field를 본다.
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.*;
    
    public class ContentGetter {
        public static void main(String[] args){
            try{
                URL u = new URL("<https://www.oreilly.com>");
                Object o = u.getContent();
                InputStream r = (InputStream) o;
                int c;
                while((c=r.read())!=-1) System.out.print((char) c);
                r.close();
                System.out.println("I got a "+o.getClass().getName());
            }catch (MalformedURLException ex){
                System.err.println(args[0] +" is not a parseable URL");
            }catch (IOException ex){
                System.err.println();
            }
        }
    }
    
  • public Object getContent(Class[] classes) throws IOException
    • Class에 제공한 순서대로 object를 가져오라는 뜻이다.
    • 만약 제공되지 않는 type이면 null을 return한다.

URL을 쪼개어 보자

  • URL의 요소들
  • Getter 함수들
    • public String getProtocol()
    • public String getHost()
    • public int getPort() → port가 명시되어 있지 않으면 -1을 리턴한다.
    • public int getDefaultPort()
    • public String getFile()
      • 첫번째 ‘/’에서 ‘#’까지를 string 형태로 return한다.
    • public String getPath()
      • query를 포함하지 않은 path만 리턴한다.
    • public String getRef()
      • fragment identifier part를 return한다. fragment identifier가 없으면 null을 리턴한다.
    • public String getQuery()
    • public String getUserInfo()
      • username+password를 리턴한다.
    • public String getAuthority()
      • userInfo + host + port를 리턴한다.

URL의 Equality와 Comparison

  • 언제 2개의 URL이 동일하다고 간주되냐면 같은 resource가 같은 host, port, path에 같은 fragment identifier와 query string이 같으면 동일하다고 한다.
  • equals() : 완전히 동일해야 한다
  • sameFile() : equals()와 같지만 fragment identifier는 고려하지 않는다.

URI Class

  • URI 문법
    • scheme : scheme-specific-part:fragment
  • URI Class 와 URL Class 의 비교
    • URI는 resource의 순수하고 identification이기 때문에 data를 얻을 함수는 없다.
    • RFC에 대해 조금 더 철저하게 다룬다
    • URI class는 protocol이 상관이 없다.
  • Methods
    • public String getScheme()
    • public String getSchemeSpecificPart()
    • public String getRawSchemeSpecificPart()
    • public String getFragment()
    • public String getRawFragment()
    raw하게 반환한다는 것은 I/O 같은 것을 I%20O 이런식으로 반환한다는 것이다.
    • public boolean isAbsolute() : URI가 scheme이 있으면 true
    • public boolean isOpaque() : URI가 hierarchical하면 false
    • public String toString() : encode되지 않은 string 형태 → I/O
    • public String toASCIIString() : encode된 URI 형태 → I%20O
    예를 들면 space는 %20이나 +로 대체된다.
    • URLEncoder.encode(String s, String encoding)
      • 이 함수는 non-ASCII character들을 모두 encode해버린다
      • 문제는 모든걸 encoding해버려서 문제가 생길 수 있다.
    • URLDecoder.decode(String s, String encoding)
      • 모든 plus sign을 space로 바꾸고 모든 percent escape를 해당하는 character로 바꾼다
    GET method로 통신하기
  • public class DMoz { public static void main(String[] args){ String target = ""; for(int i=0;i<args.length;i++){ target+="args[i]+"" ";="" }="" target="target.trim();" querystring="" query="new" querystring();="" query.add("q",target);="" try{="" url="" u="new" url("<<a="" href="https://search.yahoo.com/search?p=java&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8">https://search.yahoo.com/search?p=java&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8>"); try(InputStream in = new BufferedInputStream(u.openStream())){ InputStreamReader theHTML = new InputStreamReader(in); int c; while((c=theHTML.read())!=-1){ System.out.print((char)c); } } }catch (MalformedURLException ex){ System.err.println(ex); }catch (IOException ex){ System.err.println(ex); } } } </args.length;i++){>
  • encode form으로 반환한다는 뜻이다.

Password-Protected된 사이트에 접근하기

  • Authenticator Class
    • 추상 클래스이다.
    • methods
      • public static void setDefault(Authenticator a)
      • 만약 URL class가 username과 password를 필요로 한다면 MyAuthenticator를 물어본다.
      • getPasswordAuthentication() 함수를 override 해야한다.
        • password 인증이 필요하면 호출한다.
    • HTTP 인증 과정
      • client가 authentication info가 없는 request를 보낸다
      • server가 401을 보낸다
      • client가 authentication infor가 있는 request를 보낸다
      • server가 200을 보낸다

 

728x90
반응형

+ Recent posts