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(); } } }
- 어떤 type으로 data retrieve 할것인지 결정할 수 있다.
- public Object getContent(Class[] classes) throws IOException
- Class에 제공한 순서대로 object를 가져오라는 뜻이다.
- 만약 제공되지 않는 type이면 null을 return한다.
URL을 쪼개어 보자
- URL의 요소들
- protocol(scheme이라고도 부른다)
- authority = userinfo + host + port
- path
- fragment identifier (section이나 ref 라고도 부름)
- query string
- ex> http://www.konkuk.ac.kr/books/javaio2/index.html?isbn=02312#toc
- 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()
- 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
- URLEncoder.encode(String s, String encoding)
- 이 함수는 non-ASCII character들을 모두 encode해버린다
- 문제는 모든걸 encoding해버려서 문제가 생길 수 있다.
- URLDecoder.decode(String s, String encoding)
- 모든 plus sign을 space로 바꾸고 모든 percent escape를 해당하는 character로 바꾼다
- 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
반응형
'백엔드 > Network Programming' 카테고리의 다른 글
Non-blocking I/O in Java (0) | 2022.12.12 |
---|---|
Socket Programming(3) - Socket for Server (0) | 2022.11.21 |
Socket Programming(2) - Socket for Client (0) | 2022.11.13 |
Socket Programming(1) - socket이란? (0) | 2022.11.13 |
Internet protocols and layers (2) | 2022.09.09 |