IT_Programming/JSP · Servlet

아파치에서 배포하는 HttpClient 4.x 를 이용해 네트워크 데이터 전송

JJun ™ 2011. 11. 27. 05:28

------------------------------------------------------------------------------------------------

 출처: http://mainia.tistory.com/569

------------------------------------------------------------------------------------------------

 

 

개발환경 : JDK 1.5, window XP

 

여기에서 설명할 HttpClient 는 안드로이드 API 에 포함된 org.apache.http.client.HttpClient

가 아니다. org.apache.commons.httpclient.HttpClient 를 사용한다. 흔히 웹어플리케이션에서

가장 많이 쓰이며 Http 프로토콜을 사용해 네트워크로 데이터 전송하고 받는 역할을 한다.

HTTP 관련 아파치 사이트는 다음과 같다. http://hc.apache.org/httpclient-3.x/tutorial.html


 

 

HttpClient 의 주요 기능은 다음과 같다.

@ HTTP 버전 1.0, 1.1 을 사용한다.

@ HTTP 에서 GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE 등 모든 것이 사용 가능하다.

@ 커뮤니케이션시 HTTPS HTTP 프록시를 통해 데이터를 주고 받을수 있다.

@ 쿠키의 제어가 가능하다.

 

 

(1) POST 로 전송하는 간단한 예제

 

이 예제는 POST 로 데이터를 전송하는 간단한 내용이다.

파라미터로 데이터를 넘기며 리턴받은 데이터를 BufferedReader 로 한줄씩 읽어 들인다.

그리고 마지막에는 releaseConncetion() 호출하여 연결을 끊어준다 .

 

 

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class PostMethodExample {


  public static void main(String args[]) {
    HttpClient client = new HttpClient();
    client.getParams().setParameter("http.useragent", "Test Client");
    BufferedReader br = null;
   PostMethod method = new PostMethod("http://search.yahoo.com/search");
    method.addParameter("p", "\"java2s\"");
    try{
      int returnCode = client.executeMethod(method);

      if(returnCode == HttpStatus.SC_NOT_IMPLEMENTED) {
        System.err.println("The Post method is not implemented by this URI");
        // still consume the response body
        method.getResponseBodyAsString();
      } else {
        br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
        String readLine;
        while(((readLine = br.readLine()) != null)) {
          System.err.println(readLine);
      }
      }
    } catch (Exception e) {
      System.err.println(e);
    } finally {
      method.releaseConnection();
      if(br != null) try { br.close(); } catch (Exception fe) {}
    }
  }
}

 

 

 

(2) GET 메소드를 사용해 가장 일반적인 HTTP 데이터 전송

 

이 예제는 GET 메소드를 사용해 데이터를 보내고 요청하는 예제이다.

이것을 통해 HTTP 프로토콜에서 request response 를 얼마나 쉽게 사용할수 있는지 
알 수 있다
.
HTTPClient 는 유명한 웹 단위테스트 프레임웍인 HTMLUnit 에서도 사용되고 있다.

그리고 상세한 메뉴얼은 자카르타 홈페이지에서 참고 하도록 한다.

 

import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
public class SubmitHttpForm {
    private static String url =
         "http://localhost:8080/validatorStrutsApp/userInfo.do";
    public static void main(String[] args) {
        // Instantiate an HttpClient
        HttpClient client = new HttpClient();
        // Instantiate a GET HTTP method
        HttpMethod method = new GetMethod(url);
        // Define name-value pairs to set into the QueryString
        NameValuePair nvp1= new NameValuePair("firstName","fname");
        NameValuePair nvp2= new NameValuePair("lastName","lname");
        NameValuePair nvp3= new NameValuePair("email","email@email.com");
        method.setQueryString(new NameValuePair[]{nvp1,nvp2, nvp3});
        try{
            int statusCode = client.executeMethod(method);
            System.out.println("QueryString>>> "+method.getQueryString());
            System.out.println("Status Text>>>"
                  +HttpStatus.getStatusText(statusCode));
            // Get data as a String
            System.out.println(method.getResponseBodyAsString());
            // OR as a byte array
            byte [] res  = method.getResponseBody();
            // write to file
            FileOutputStream fos= new FileOutputStream("donepage.html");
            fos.write(res);
            // release connection
            method.releaseConnection();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
} 

 

 

(3) 쿠키관리를 위한 HttpClient 사용

 

HttpClient 에서는 프로그램에서 어떻게 쿠키를 효과적으로 관리할수 있을지에 대한 방법을 제공한다. 아래 예제는 쿠키정보를 requst 로 서버에 보내고 있으며 JSP 페이지에서 쿠키 세부정보에 대해 리스트를 보여준다 

 

 

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;

public class CookiesTrial {

    private static String url =
         "http://127.0.0.1:8080/HttpServerSideApp/CookieMgt.jsp";

    public static void main(String[] args) throws Exception {

        // A new cookie for the domain 127.0.0.1
        // Cookie Name= ABCD   Value=00000   Path=/  MaxAge=-1   Secure=False

        Cookie mycookie = new Cookie("127.0.0.1", "ABCD", "00000", "/", -1, false);

        // Create a new HttpState container
        HttpState initialState = new HttpState();
        initialState.addCookie(mycookie);

        // Set to COMPATIBILITY for it to work in as many cases as possible
        initialState.setCookiePolicy(CookiePolicy.COMPATIBILITY);
        // create new client
        HttpClient httpclient = new HttpClient();
        // set the HttpState for the client
        httpclient.setState(initialState);

        GetMethod getMethod = new GetMethod(url);
        // Execute a GET method
        int result = httpclient.executeMethod(getMethod);

        System.out.println("statusLine>>>"+getMethod.getStatusLine());

        // Get cookies stored in the HttpState for this instance of HttpClient
        Cookie[] cookies = httpclient.getState().getCookies();

        for (int i = 0; i < cookies.length; i++) {
            System.out.println("nCookieName="+cookies[i].getName());
            System.out.println("Value="+cookies[i].getValue());
            System.out.println("Domain="+cookies[i].getDomain());
        }

        getMethod.releaseConnection();
    }
}

 

 

JSP
페이지에서 클라이언트에서 서버로 전송된 쿠키들에 대한 세부정보를 보여주는 예제이다.

참고로 HttpClient 에서는 org.apache.commons.httpclient.Cookie 클래스를 쓰며

JSP Servlet 에서는 javax.servlet.http.Cookie 클래스를 사용한다.

 


<% Cookie[] cookies= request.getCookies(); for (int i = 0; i < cookies.length; i++) { System.out.println(cookies[i].getName() +" = "+cookies[i].getValue()); } // Add a new cookie response.addCookie(new Cookie("XYZ","12345")); %> 

 

 

 

(4) 파일 업로드를 위한 HttpClient 사용

 

이번에는 2가지 파일 업로드 예제이다. 첫번째는 일반적인 HTML form 에서 파일컨트롤을 이용해
업로드 하는 방법이며
HttpClient 를 사용하지 않았다. 2번쨰는 HttpClient 를 이용해
업로드 하는
java application 이다. 두 방법 모두 ProcessFileUpload.jsp를 이용한다


(1)
일반적인 HTML 폼을 이용한 파일 업로드

 

UploadFiles.html

 
<HTML>
  <HEAD></HEAD>
<BODY> Upload Files <FORM encType=multipart/form-data method=post name=filesForm action=ProcessFileUpload.jsp> File 1:<INPUT name=file1 type=file><BR> File 2:<INPUT name=file2 type=file><BR> File 3:<INPUT name=file3 type=file><BR> <INPUT name=Submit value="Upload Files" type=submit> </FORM> </BODY>
</HTML>
 

 

ProcessFileUpload.jsp

 
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ page import="org.apache.commons.fileupload.DiskFileUpload"%>
<%@ page import="org.apache.commons.fileupload.FileItem"%>
<%@ page import="java.util.List"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.io.File"%>
<HTML> <HEAD>
<%
        System.out.println("Content Type ="+request.getContentType());
        DiskFileUpload fu = new DiskFileUpload();
        // If file size exceeds, a FileUploadException will be thrown
        fu.setSizeMax(1000000);
        List fileItems = fu.parseRequest(request);
        Iterator itr = fileItems.iterator();
        while(itr.hasNext()) {
          FileItem fi = (FileItem)itr.next();
          //Check if not form field so as to only handle the file inputs
          //else condition handles the submit button input
          if(!fi.isFormField()) {
            System.out.println("nNAME: "+fi.getName());
            System.out.println("SIZE: "+fi.getSize());
            //System.out.println(fi.getOutputStream().toString());
            File fNew= new File(application.getRealPath("/"), fi.getName());
            System.out.println(fNew.getAbsolutePath());
            fi.write(fNew);
          }
          else {
            System.out.println("Field ="+fi.getFieldName());
          }
        }
%>
</HEAD>




<BODY>
Upload Successful!!
</BODY>
<HTML>

 

 

(2) HttpClient 를 이용해 다중파일 업로드

HTML 이 아닌 java application 에서 파일을 다중으로 업로드 할 때 사용되는 방식이다.

파일을 다중으로 올릴수 있도록 제공해주는 클래스는 org.apache.commons.httpclient.

methods.MultipartPostMethod 이다. 그리고 HttpClient 를 이용해 멀티폼 전송을 할 때
주로 참조하는 클래스들은
org.apache.commons.httpclient.methods.multipart 패키지에

존재한다.

 

 
import java.io.File;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.MultipartPostMethod;
public class HttpMultiPartFileUpload {
    private static String url =
      "http://localhost:8080/HttpServerSideApp/ProcessFileUpload.jsp";
    public static void main(String[] args) throws IOException {
        HttpClient client = new HttpClient();
        MultipartPostMethod mPost = new MultipartPostMethod(url);
        client.setConnectionTimeout(8000);
        // Send any XML file as the body of the POST request
        File f1 = new File("students.xml");
        File f2 = new File("academy.xml");
        File f3 = new File("academyRules.xml");
        System.out.println("File1 Length = " + f1.length());
        System.out.println("File2 Length = " + f2.length());
        System.out.println("File3 Length = " + f3.length());
        mPost.addParameter(f1.getName(), f1);
        mPost.addParameter(f2.getName(), f2);
        mPost.addParameter(f3.getName(), f3);
        int statusCode1 = client.executeMethod(mPost);
        System.out.println("statusLine>>>" + mPost.getStatusLine());
        mPost.releaseConnection();
    }
}

 

위의 예제를 통해 HttpClient FileUpload 컴퍼넌트를 어떻게 사용하는지 알았을 것이다. HttpClient HTTP 프로토콜을 사용해 커뮤니케이션을 하고자 하는 어떤 프로그램에서도
손쉽게 사용할수 있다는 걸 알 수 있다
.

 

좀더 세밀한 제어는 자카르타 홈페이지에 들어 매뉴얼을 참고하고 앞으로 진행할 프로젝트 등에
유용하게 사용하기 바란다