url connection2014. 8. 14. 11:56
URLConnection, InputStream / InputStreamReader 자바


복사 http://blog.naver.com/48milk/220070139984 

* URL 주소를 통해 연결

 

String url = "http://url연결할 주소입력";

 

URL u = new URL(url);

URL 객체를 생성하려면

public URL(String spec) throws MalformedURLException 메소드를 타기 때문에

try ~ catch 문으로 예외처리를 해줘야한다.

import java.net.URL; <- import 하는 것도 잊지 않고!

 

URLConnection uc = u.openConnection();

생성한 URL객체를 통해 연결을 완성할 수 있다.

import java.net.URLConnection; <- 이것도 import.

 

 

 

* 콘텐츠 읽기

 

자바에서 어떤 콘텐츠를 읽어들이기 위해 InputStream을 사용하는데,

여기서는 위에 URL 주소에서 받은 파일 내용을 읽을 것이다.

 

InputStream is = uc.getInputStream();

InputStream 객체에 연결된 URL의 내용을 받아온다.

import java.io.InputStream;

 

InputStreamReader isr = new InputStreamReader(is, "UTF-8");

InputStreamReader를 통해 InputStream으로 입력받은 내용을 읽어들이는데,

이때, InputStreamReader 객체 생성시 입력되는 파라미터 "UTF-8"은 ChracterSet을 의미한다.

자세한 건 API 참조하는 게 나을듯

import java.io.InputStreamReader;

 

BufferedReader br = new BufferedReader(isr);

Buffer를 사용하는 이유는 처리속도를 더 빠르게 하기 위해.

import java.io.BufferedReader;

Scanner s = new Scanner(br);

String str = "";

while(s.hasNext()) {

str += s.nextLine();

}

System.out.println(str);

 

대략 이런 식으로 하면 파일 읽기를 할 수 있을 것이다.

 

 

실제로 인터페이스를 하는 과정에서 url 주소를 통해 xml 소스 파일을 넘겨받아올 때

한글도 포함되어 있어서 UTF-8 처리를 해주었다.

 

원래는 xml 파일 자체를 파싱하여 처리해주었지만,

파일을 읽어들이는 과정에서 이미 InputStream을 하기 때문에

url로 호출하면 파일을 파싱하기 보다 호출된 내용을 그대로 사용하는 편이 더 빨라서

파일 파싱하는 부분은 생략.

 


Posted by wrnly
url connection2014. 8. 10. 11:18
첨부파일(2)

import java.net.*;
import java.io.*;
public class URLTest {
public static void main(String[] args) {
try{
URL url=
new URL("http://news.naver.com/main/"
+ "read.nhn?mode=LSD&mid=shm&"
+ "sid1=103&oid=001&"
+ "aid=0007031606");
URL url1=
new URL("http","news.naver.com",80,"/main/"
+ "read.nhn?mode=LSD&mid=shm&"
+ "sid1=103&oid=001&"
+ "aid=0007031606");
//URL (String  protocol, String  host, int port, String  file)
System.out.println(url.getContent());
InputStream ins=url1.openStream();
FileOutputStream fio=new FileOutputStream("test.html");
BufferedWriter bw=new BufferedWriter(
new OutputStreamWriter(fio)
);
BufferedReader in=new BufferedReader(
new InputStreamReader(ins)
);
String str="";
while((str=in.readLine())!=null){
System.out.println(str);
bw.write(str);
}
in.close();
bw.close();
System.out.println("port:"+url.getDefaultPort());
System.out.println(url.getHost());
System.out.println(url.getProtocol());
System.out.println(url.getPath());
System.out.println(url.getFile());
System.out.println(url.getQuery());
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}

======================================================
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
import java.security.Permission;
import java.util.List;
import java.util.Map;
public class HttpURLConnectionTest extends HttpURLConnection {

protected HttpURLConnectionTest(URL u) {
super(u);
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws Exception{
URL url=new URL("http://news.naver.com/main/"
+ "read.nhn?mode=LSD&mid=shm&"
+ "sid1=103&oid=001&"
+ "aid=0007031606");
HttpURLConnection huc=new HttpURLConnectionTest(url);
System.out.println(huc.HTTP_OK);
System.out.println(huc.getContentType());
System.out.println(huc);
System.out.println(huc.getDate());
System.out.println(huc.getExpiration());
System.out.println(huc.getDoInput());
// System.out.println((String)huc.getContent());
}
@Override
public void disconnect() {
// TODO Auto-generated method stub
System.out.println("연결종료");
}
@Override
public boolean usingProxy() {
// TODO Auto-generated method stub
System.out.println("방화벽 사용 안함");
return false;
}
@Override
public void connect() throws IOException {
// TODO Auto-generated method stub
System.out.println("연결시작");
}

}



Posted by wrnly
url connection2011. 9. 20. 20:57

이 글은 HttpURLConnection 과 이의 서브클래스인 HttpsURLConnection 을 사용하여 보안 웹 페이지에 액세스하는 방법을 보여준다. 또한 비보안 페이지(non-secure page)에서 보안 페이지(secure one)로의 리다이렉트를 쉽게 할 수 있는 방법도 볼 수 있다. HTTP 와 HTTPS에 관한 정보는 HTTP 1.1 RFC 2616HTTPS RFC 2818를 참고하기 바란다.

첫번째 예로, 주어진 URL에 접속하기 위해 다음 WebPageReader 프로그램의 HttpURLConnection 를 이용해 보자. 그리고 페이지의 내용을 스탠다드 아웃(standard out)에 출력하자.

   import java.net.URL;
   import java.net.MalformedURLException;
   import java.net.URLConnection;
   import java.io.IOException;
   import java.io.BufferedReader;
   import java.io.InputStreamReader;

   public class WebPageReader {

      private static URLConnection connection;

      private static void connect( String urlString ) {
        try {
          URL url = new URL(urlString);
          connection = url.openConnection();
        } catch (MalformedURLException e){
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      private static void readContents() {
        BufferedReader in = null;
        try {
          in = new BufferedReader(
            new InputStreamReader(
              connection.getInputStream()));

          String inputLine;
          while (
            (inputLine = in.readLine()) != null) {
            System.out.println(inputLine);
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      public static void main(String[] args) {
        if (args.length != 1) {
          System.err.println("usage: java WebPageReader "
                                             + "<url>");
          System.exit(0);
        }
        connect(args[0]);
        readContents();
      }
   }

만약 현재의 위치가 방화벽 뒤라면, 다음과 같이 설정된 proxyHostproxyPort 변수들이 필요하다.

   http.proxyHost=webcache
   http.proxyPort=8080

   https.proxyHost=webcache
   https.proxyPort=8080

커맨드 라인에 -D플래그를 이용해서 값을 직접 입력하거나 프로그램 상에서 System.setProperty()를 호출함으로써 변수를 구할 수있다. WebPageReader 를 컴파일한 후에 이하와 같은 커맨드로 Core Java Technologies Tech Tips 홈 페이지의 내용을 열거해 볼 수 있다.

   java WebPageReader 
     http://java.sun.com/developer/JDCTechTips/

URLConnection는 추상 클래스이다. URL클래스의 openConnection() 메소드는 지정된 URL을 읽을 수 있도록 적절하고 구체적인 서브클래스를 리턴한다. http나 https URL을 입력하면 이는 HttpURLConnectionHttpsURLConnection의 서브클래스가 될 것이다. 만약 다음을 openConnection()를 호출하는 라인에 추가하면,

   System.out.println(connection.getClass());

HttpURLConnection의 숨겨진 구현 클래스의 인스턴스를 리턴하는 커넥션(connection)을 보게 된다. 예를 들면, 다음과 같다.

   class sun.net.www.protocol.http.HttpURLConnection

이와 유사하게 보안 페이지를 읽기 위해 동일한 WebPageReader코드를 사용할 수가 있다.

   java WebPageReader https://today.dev.java.net

후자의 경우, 커넥션은 HttpsURLConnection의 서브클래스인 HttpURLConnection타입이라는 것을 알아야 한다. 보다 명확하게 말하자면 다음과 같은 숨어있는 구현 클래스가 있다는 것을 인식할 수 있어야 한다.

   class sun.net.www.protocol.https.HttpsURLConnectionImpl

일반적으로 브라우저에 URL을 입력할 때, 이동하고자하는 페이지가 보안 페이지인지 아닌지는 알 수가 없다. 다시 말하면, today.dev.java.net 페이지를 보기 위해서는 http://today.dev.java.net를 입력한다. 필요하다면 브라우저가 리다이렉트할 것이고 사용자를 https://today.dev.java.net로 연결하기 위해 적절한 신호변경을 수행한다. WebPageReader프로그램이 요청된 리다이렉션을 수행하는지를 살펴보자.

   java WebPageReader http://today.dev.java.net

원하는 페이지로 리다이렉트되는 대신에 다음과 같은 메시지를 보게 된다.

   <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
   <HTML><HEAD>
   <TITLE>301 Moved Permanently</TITLE>
   </HEAD><BODY>
   <H1>Moved Permanently</H1>
   The document has moved
   <A HREF="https://today.dev.java.net/">here</A>.<P>
   <HR>
   <ADDRESS>
      Apache/1.3.26 Server at today.dev.java.net Port 80
   </ADDRESS>
   </BODY></HTML>

이 정보로부터 무언가를 읽어내는 것은 어렵지만 문제는 리다이렉션에 관한 것이 아니다. URL http://linux.java.net으로 프로그램을 실행하면, 프로그램은 http://community.java.net/linux으로 적절히 이를 리다이렉트하고 사용자는 원하는 컨텐츠를 볼 수가 있다. 어떤 일이 일어나는지를 자세히 살펴보려면 HttpURLConnection를 명시적으로 이용해야 한다. 스탠다드 아웃에 웹 페이지의 컨텐츠를 출력하는 코드를 삭제해서 일을 간단히 해보자. RedirectingReader프로그램이다.

   import java.net.URL;
   import java.net.MalformedURLException;
   import java.net.HttpURLConnection;
   import java.io.IOException;

   public class RedirectingReader {

      private static HttpURLConnection connection;

      private static void connect( String urlString ) {
        try {
          URL url = new URL(urlString);
          connection
              = (HttpURLConnection)url.openConnection();
          System.out.println(connection.getURL());
          System.out.println(
              connection.getResponseCode() +
              " " + connection.getResponseMessage());
          System.out.println(connection.getURL());
        } catch (MalformedURLException e){
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      public static void main(String[] args) {
        if (args.length != 1) {
          System.err.println(
               "usage: java WebPageReader "
               + "<url>");
          System.exit(0);
        }
        connect(args[0]);
      }
   }

다음과 같이 리다이렉트하는 URL을 입력하여 RedirectingReader 를 컴파일하고 실행해 보자.

   java RedirectingReader http://linux.java.net/

다음과 같은 출력값을 보게 될 것이다.

   http://linux.java.net/
   200 OK
   http://community.java.net/linux/

첫번째 라인이 재빨리 나타난다. String값으로 URL을 생성하고 HttpURLConnection객체를 실행하자. 그러면 http://linux.java.net를 요청하는 동안에 잠깐의 멈춤이 생긴다. 페이지가 리다이렉트되는 이 시간동안 받게 되는 응답 코드와 메시지는 리다이렉트된 페이지로부터 온 것이다. 이 리다이렉트된 페이지는 출력값의 3번째 라인에 열거된다. URL url = new URL(urlString);아래의 라인을 추가해서 리다이렉션을 허용하지 않았을 때 발생하는 현상을 보자.

   HttpURLConnection.setFollowRedirects(false);

출력값은 다음과 같다.

   http://linux.java.net/
   302 Found
   http://linux.java.net/

이는 302 에러가 발생했다는 것을 나타낸다. 곧 리다이렉트되지 않고 URL이 그대로 유지되었다는 것이다. 이를 처리하기 전에, 좀 전에 추가했던 라인을 지우고 리다이렉션이 다시 작동하는지를 확인하기 위해 RedirectingReader 프로그램을 실행시켜보자. RedirectingReader를 다시 한번 실행시키고, http://today.dev.java.net 를 입력하자. 다음과 같은 출력값을 보게 된다.

   http://today.dev.java.net
   301 Moved Permanently
   http://today.dev.java.net

위는 이 프로그램이 "Moved Permanently" 에러를 처리할 수 없어서 리다이렉트 했다는 것을 말한다. 이것이 바로 원했던 디폴트 속성이다. 보안문제 때문에 http 과 https간에는 리다이렉트할 수 없다. 어디로 리다이렉트할 것이냐하는 정보는 이 응답의 헤더 부분에 있다. 이전의 요청에 대한 전체 응답 헤더는 다음과 같다.

   HTTP/1.1 301 Moved Permanently
   Date: Tue, 03 Feb 2004 01:38:43 GMT
   Server: Apache/1.3.26 (Unix) mod_ssl/2.8.10 
   OpenSSL/0.9.6b
   mod_jk/1.2.1
   Location: https://today.dev.java.net/
   Content-type: text/html; charset=iso-8859-1

HttpURLConnection 내의 getResponseCode()getResponseMessage() 메소드가 이 응답의 첫번째 라인에 포함된 정보를 리턴하는 것을 본 적이 있을 것이다. 혹은 getHeaderField() 메소드를 이용해서 헤더 필드의 이름에 스트링값을 넣어주어도 된다. 가령, getHeaderField("Location")는 https://today.dev.java.net/값을 리턴한다.

이 글의 시작부분에서 언급했던 HTTP 1.1 과 HTTPS RFCs에서 요청과 응답 헤더의 포맷에 관해 자세히 살펴 볼 수 있다. 300 레벨 응답에서, "Location:"는 리다이렉션을 위한 위치값을 제공해야만 한다. 301나 302 에러를 발생하는지를 확인하기 위해 다음 사항을 추가하자.

   private static boolean mustRedirect(int code){
      if (code == HttpURLConnection.HTTP_MOVED_PERM ||
          code == HttpURLConnection.HTTP_MOVED_TEMP)  {
      System.out.println("Received error " + code +
                         ", trying secure redirect");
        return true;
      } else return false;
   }

리다이렉트가 자동적으로 처리되지 않는다면 사용자는 301 나 302 응답 코드만을 받게 된다는 것을 기억하자. 지금까지 이것은 리다이렉트가 HttpURLConnection가 아닌 HttpsURLConnection가 필요하다는 것을 의미했다. "Location:" 필드에 제공된 정보를 따르자. 다음과 같이 새로운 정보를 이용해서 url 값과 커넥션을 재설정하자.

   url = new URL("https://"+ url.getHost()
                                + url.getFile());
   connection
        = (HttpsURLConnection)url.openConnection();

마지막으로, 웹 리더를 받기 위해 위의 모든 사항을 모으고 필요할 때 보안 페이지로 리다이렉트될 수 있도록 하자.

   import javax.net.ssl.HttpsURLConnection;
   import java.net.URL;
   import java.net.MalformedURLException;
   import java.net.HttpURLConnection;
   import java.io.IOException;
   import java.io.BufferedReader;
   import java.io.InputStreamReader;

   public class RedirectingReader {
     private static HttpURLConnection connection;
     private static URL url;

     private static void connect(String urlString) {
       try {
         url = new URL(urlString);
         connection
           = (HttpURLConnection) url.openConnection();
         int code = connection.getResponseCode();
         if (mustRedirect(code))
          secureRedirect(
            connection.getHeaderField("Location"));
         readContents();
       } catch (MalformedURLException e) {
         e.printStackTrace();
       } catch (IOException e) {
         e.printStackTrace();
       }
     }

     private static boolean mustRedirect(int code) {
       if (code == HttpURLConnection.HTTP_MOVED_PERM ||
         code == HttpURLConnection.HTTP_MOVED_TEMP) {
         return true;
       } else
         return false;
     }

     private static void secureRedirect(String location)
       throws IOException {
       System.out.println(location);
       url = new URL(location);
       connection
         = (HttpsURLConnection) url.openConnection();
     }

     private static void readContents() {
       BufferedReader in = null;
       try {
         in = new BufferedReader(
           new InputStreamReader(
             connection.getInputStream()));

         String inputLine;
         while ((inputLine = in.readLine()) != null) {
           System.out.println(inputLine);
         }
       } catch (IOException e) {
         e.printStackTrace();
       }
     }

     public static void main(String[] args) {
       if (args.length != 1) {
         System.err.println("usage: java WebPageReader "
           + "<url>");
         System.exit(0);
       }
       connect(args[0]);
     }
   }

업데이트된 RedirectingReader 를 컴파일하고 동작이 제대로 이루어지는지 확인하기 위해 몇 개의 다른 입력값을 넣어 실행해보자. 예를 들면 http://today.dev.java.net 와 http://linux.java.net를 넣어보자. 리다이렉트되지 않는 보안페이지와 비보안 페이지를 입력해서 RedirectingReader를 실행해도 동작이 적절하게 이루어져야 한다. 이제 다시 뒤로 돌아가서 최초 WebReader 프로그램에 모든 println() 메소드를 제거하고 readContents()를 추가할 수 있다

 

 


'url connection' 카테고리의 다른 글

URLConnection, InputStream / InputStreamReader  (0) 2014.08.14
URL, URLConnection(java)  (0) 2014.08.10
Posted by wrnly