IT_Programming/JSP · Servlet

Java Open Source HttpClient and FileUpload

JJun ™ 2011. 11. 27. 01:02

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

 출처: http://rogerrb.blogspot.com/2009/07/httpclient-and-fileupload.html 

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

 

 

 August 2004 Discuss this Article
 Adapted from: Pro Jakarta Commons, by Harshad Oak
 Publisher: Apress
 ISBN: 1590592832

 
인터넷 상에서 이루워지는 모든 커뮤니케이션은 파일 전송 프로토콜 (FTP), 단순 전자우편 전송

프로토콜 (SMTP), 우체국 통신 규약 (POP), 하이퍼 텍스트 전송 프로토콜 (HTTP) 과 같은

표준 프로토콜을 사용하여 이루어진다.

 

HTTP World Wide Web상에서 가장 필수적이고 가장 대중적인 프로토콜이다
오늘날 많은 어플리케이션 폭넒게 사용하는 프로토콜이다.

 

만일 자바어플리케이션이
HTTP을 사용하여 상호 작용한다면 HTTPClient 컴포넌트는 조금 더 쉽게 할 수 있는 방식을 제공한다. 이 컴포넌트를 사용한다면 HttpClient컴포넌트에서 제공하는 클래스와 메소드을 이용함으로 프로토콜의 기술적인 측면에서의 걱정을 해소할수 있다.

Article에서는 HTTPClient 컴포넌트의 몇가지 사용예를 살펴볼 것이다.
우리는 서버측 파일 업로드 업무을 지원하는 FileUpload 컴포넌트에 대하여서도 간단하게
살펴 볼 것이다
.

그리고 마지막으로 우리는 HTTPClient FileUpload컴포넌트을 함께 사용한 예를 살펴 볼 것이다.


NOTE
:
Article에서 작성된 모든 예제는 Tomcat 4.0.6이상 버전에서 테스트 되었습니다.
컴포넌트 설치 : http://jakarta.apache.org/commons/index.html에서 위 두가지의 컴포넌트를
다운로드 받을수 있다
. 이 글을 사용하고 있는 현재 두 컴포넌트의 버전은 다음과 같다.

두 컴포넌트는 내부적으로 commons-logging 컴포넌트을 사용함으로 같이 설치 해줘야
합니다.
l HTTPClient 3.0 Alpha
l FileUpload 1.0

 

 

 

Introducing HttpClient

 

HttpClient
HTTP상에서 커뮤니케이션을 하는 자바 기반의 어플리케이션 개발을 쉽게 할 수
있도록 제공한다. 우리가 웹 브라우저 또는 그에 준하는 어플리케이션을 개발한다면 HttpClient
우리에게 클라이언트 코드 개발에 도움을 줄 수 있다.

 

이름에서 의미하는것과 같이
HttpClient는 오직 HTTP 클라이언트 코드을 위한 컴포넌트이지
HTTP
요청을 처리하는 서버측 프로세스을 지원하지는 않는다.

HttpClient
는 다음과 같은 특징을 가지고 있다.

l HTTP 버전 1.0, 1.1을 구현한다.
l HTTP 메소드 GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE을 구현한다.
l HTTPS Proxies을 이용한 연결을 지원한다.
l Basic, Digest, NT 근거리 통신 매니저(NTLM)을 이용한 인증을 지원한다.
l Cookie 핸들링 

 

 

 

Using HttpClient


HttpClient
Commons Logging 컴포넌트인 commons-logging.jar을 사용한다.
이는 자카르타 아파치 Common프로젝트 사이트에서 다운받을 수 있다.

 

 

Using the GET Method

 

Get
메소드는 대부분의 HTTP 요청을 보내는 방식이다.
하이퍼 링크 같은 경우는 GET방식의 대표적이라 할 수 있겠다.
여기서 HttpClient GET방식 요청 예제를 살펴본다.

 

이 샘플을 테스트 하기전에 서버측에는 요청에 응답을 할 수 있는
Servlet을 등록해야 한다.
여기서는 userInfo클래스을 userinfo.do라는 명칭으로 매핑시켜 사용한다.
그리고 클라이언트에서 서버측으로 전송되는 파라미터는 , firstname, lastname, email 3가지 이다.

 

서버측
Servlet
package httpClient;

 

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import java.util.Enumeration;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class userInfo extends HttpServlet  
{
       private static final String CONTENT_TYPE = "text/html; charset=MS949";
 
       public void init(ServletConfig config) throws ServletException

       {

              super.init(config);
       }
      

 

       public void doGet(HttpServletRequest request, HttpServletResponse response)
                                                                          throws ServletException, IOException

       {

              System.out.println("UserInfo GET Method Call -->");
              this.doProcess(request, response);
       }
 
       public void doPost(HttpServletRequest request, HttpServletResponse response)
                                                                            throws ServletException, IOException 
       {
             System.out.println("UserInfo POST Method Call -->");
             this.doProcess(request, response);
       }
 
       public void doProcess(HttpServletRequest request, HttpServletResponse response)
                                                                            throws ServletException, IOException

       {

             response.setContentType(CONTENT_TYPE);
             PrintWriter out = response.getWriter();
 
             java.util.Enumeration e= request.getHeaderNames();
             while (e.hasMoreElements())
             {
                    String headerName = (String)e.nextElement();
                    System.out.println(headerName +" = "+request.getHeader(headerName));
             }
 
             ServletInputStream ins = request.getInputStream();
             ByteArrayOutputStream outs = new ByteArrayOutputStream();
             byte[] buffer = new byte[1024];
             int read = 0;
             while ((read = ins.read(buffer, 0, 1024)) != -1)

             {

                   outs.write(buffer, 0, read);
             }
             System.out.println(outs.toString());
 
             out.println("<html>");
             out.println("<head><title>userInfo</title></head>");
             out.println("<body>");
             out.println("<p>The servlet has received.</p>");
 
             Enumeration names = request.getParameterNames();
             String name = "";
             while(names.hasMoreElements())
             {
                  name = names.nextElement().toString();
                  System.out.println(name +" : "+request.getParameter(name));
                  out.println("<p>"+name +" : "+request.getParameter(name)+"</p>");
             }
 
             out.println("</body></html>");
             out.close();
       }
}

 

 

 

 

Web.xml Servlet 등록

 

<servlet>
      <servlet-name>userInfo</servlet-name>
      <servlet-class>httpClient.userInfo</servlet-class>
</servlet>

<servlet-mapping>
     <servlet-name>userInfo</servlet-name>
     <url-pattern>/userinfo.do</url-pattern>
</servlet-mapping>

 

 

 

HttpClient
코드
import java.io.FileOutputStream;
import java.io.IOException;
 
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
 
public class SubmitHttpForm
{
 
        private static String url = "http://15.32.37.194:8988/HttpClient/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();
            }
       }
}

 

 

 

서버 측 로그

UserInfo GET Method Call -->
USER-AGENT = Jakarta Commons-HttpClient/2.0.1
HOST = 15.32.37.194:8988
email : email@email.com
lastName : lname
firstName : fname
 


위 예제는 서버측으로 클라이언트 요청을 보내고 요청에 대한 응답을 받아서
“donepage.html”이라는 파일에 응답내용을 저장하는 클라이언트입니다.

 

org.apache.commons.httpclient.HttpStatus
클래스에는 요청에 대한 응답 코드에 대한

상태 가정이 되어있습니다.


우리는 GET메소드을 사용하여 Name/Value쌍의 파라미터를 전송하는 방식을 간단하게 살펴
보았습니다
.
 

 

 

Using the POST Method

이번 예제에서는
XML 문서을 HTTP POST 메소드로 서버측에 보내는 예제를 살펴볼 것이다.

전송될
XML문서 post.xml

<?xml version='1.0' encoding='KSC5601'?>
<PERSONS>
    <PERSON>
        <FIRSTNAME>Yun Chang</FIRSTNAME>
        <LASTNAME>LEE</LASTNAME>
        <EMAIL>craftlee@nate.com</EMAIL>
    </PERSON>
</PERSONS>

Post
전송 HttpClient 코드
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
 
public class PostAFile
{
     private static String url = "http://15.32.37.194:8988/HttpClient/userinfo.do";
 
     public static void main(String[] args) throws IOException
     {
          HttpClient client = new HttpClient();
          PostMethod postMethod = new PostMethod(url);
 
          client.setConnectionTimeout(8000);
 
          // Send any XML file as the body of the POST request
          File f = new File("post.xml");
          System.out.println("File Length = " + f.length());
 
          postMethod.setRequestBody(new FileInputStream(f));
          postMethod.setRequestHeader("Content-type", "text/xml; charset=KSC5601");
 
          int statusCode1 = client.executeMethod(postMethod);
          System.out.println("statusLine>>>" + postMethod.getStatusLine());
          postMethod.releaseConnection();
     }
}

 

 

서버 측 로그

UserInfo POST Method Call -->
CONTENT-TYPE = text/xml; charset=KSC5601
USER-AGENT = Jakarta Commons-HttpClient/2.0.1
HOST = 15.32.37.194:8988
CONTENT-LENGTH = 195

<?xml version='1.0' encoding='KSC5601'?>
<PERSONS>
     <PERSON>
           <FIRSTNAME>Yun Chang</FIRSTNAME>
           <LASTNAME>LEE</LASTNAME>
           <EMAIL>craftlee@nate.com</EMAIL>
     </PERSON>
</PERSONS>
 

이 방식은 파일 첨부방식을 나타내는 것이기도 하다
.
우리가 쓰고있는 FileUpLoad 컴포넌트도 이와 같은 방식을 사용하고 있다.


Managing Cookies

Cookie
관리 예제를 살펴본다.


서버측
JSP

<%@ page contentType="text/html;charset=MS949"%>
<%
       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"));
%>

 

 

HttpClient
코드
package httpClient;
 
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://15.32.37.194:8988/HttpClient/cookieServer.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("15.32.37.194", "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();
      }
}


결과

statusLine>>>HTTP/1.1 200 OK
 
CookieName=ABCD
Value=00000
Domain=15.32.37.194
 
CookieName=XYZ
Value=12345
Domain=15.32.37.194
 
CookieName=JSESSIONID
Value=ac3f1396ad9b4a2b8f8e939eb75c843d
Domain=15.32.37.194
Process exited with exit code 0.

CAUTION

HttpClient
코드는 org.apache.commons.httpclient.Cookie클래스을 이용하고,
JSP
servlet코드는 javax.servlet.http.Cookie 클래스을 이용한다.


HTTPS and Proxy Servers

HttpClient
HTTPS 프로토콜도 통상의 URLs를 인식하고 구동된다.
HTTPS
프로토콜은 Secure Soocket Extension(JSSE) 시스템에 설치 되어있어야 하며
JSSE
JSDK1.4 버전이상에서는 포함되어 있으며 이하 버전에서는 별로의 설치해야 한다.
만일 porxy서버을 통한 접속일 경우 다음과 같이 PROXYHOST, Port을 넣어주면 된다.
HttpClient client = new HttpClient();
HostConfiguration hConf= client.getHostConfiguration();
hConf.setProxy("PROXYHOST ", 9999);


Introducing FileUpload

FileUpload
컴포넌트는 서버측에 파일 첨부을 쉽게 해줍니다.
FileUpload
컴포넌트는 클라이언트 단이 아닌 서버측에서사용된다는것에 주의 해야합니다.
파일 첨부의 시작은 HTML을 이용하며 서버측에서는 FileUpload 컴포넌트을 사용합으로
쉽게 처리하고, 적당한 위치에 저장할수 있습니다.

Using HTML File Upload
다들 아시는 부분이라 이부분의 설명은 제외하고 예제 소스를 바로 살펴봅니다.

fileUP.html
<HTML>

 

<HEAD>
     <META http-equiv="Content-Type" CONTENT="text/html; charset=windows-1252"/>
     <TITLE>File Upload Page</TITLE>
</HEAD>

 

<BODY>Upload Files
     <FORM name="filesForm" action="ProcessFileUpload.jsp" method="post"
                 enctype="multipart/form-data">
    

            File 1:<input type="file" name="file1"/><br/>

            File 2:<input type="file" name="file2"/><br/>
            File 3:<input type="file" name="file3"/><br/>

            <input type="submit" name="Submit" value="Upload Files"/>
     </FORM>
</BODY>

 

</HTML>

파일 업로드의 시작점은
HTML Form의 속성이
method="post" enctype="multipart/form-data"
이어야 합니다. FileUpload 컴포넌트는 enctype에 의해서 전송되는 파라미터를 inputStream으로 받을지
Reader
로 받을지 결정합니다.

서버측 프로그램 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>
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
        <title>Process File Upload</title>
</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());
                     }
               }
         %>

 

<body>
        Upload Successful!!
</body>

 

</html>


Using HttpClient-Based FileUpload

위 단에서
HTML의 역할을 HttpClient을 이용하여 작성하여본다.
JSP파일의 내용은 변함이 없고 클라이언트 코드을 변경함으로써 가능하다.
HttpClient 컴포넌트는 multipart-encoded을 지원하기 위해 다음과 같은 클래스를 제공합니다. org.apache.commons.httpclient.methods.MultipartPostMethod 이 클래스을 이용하여 예제를 작성해 봅니다.

HttpClient
코드
package httpClient;
 
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://15.32.37.194:8988/HttpClient/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 사용하기