상세 컨텐츠

본문 제목

[JAVA] Http 송수신 HttpClient

JAVA

by AlrepondTech 2020. 9. 17. 18:17

본문

반응형

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

httpClient.txt
0.02MB
httpcomponents-client-4.1.1-bin.zip
2.78MB
자카르타_프로젝트_HttpClient와_FileUpload_사용.doc
0.33MB

 

기타 참고: http://kkamsang486.tistory.com/48

 

 

 

=================================

=================================

=================================

 

 

 

 

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();

        }

    }

 

 

 

=================================

=================================

=================================

 

 

 

 

 

출처  http://programmers.tistory.com/207

 

#### 1. 설명 및 설치

1-1. HttpClient 소개

HttpClient은 HTTP상에서 커뮤니케이션을 하는 자바 기반의 어플리케이션 개발을 쉽게 할수 있도록 제공한다. 

우리가 웹 브라우저 또는 그에 준하는 어플리케이션을 개발한다면 HttpClient은 우리에게 클라이언트 코드 개발에 도움을 줄수있다.

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

 

1-2. 설치

현재 아파치 HttpClient 는 3.0.1 안정버전을 지원한다.

Jakarta Commons HttpClient 페이지에서 다운로드 받으면 된다.

(다운로드 페이지: http://jakarta.apache.org/commons/httpclient/downloads.html)

(최신버전 다운로드:

  - http://jakarta.apache.org/site/downloads/downloads_commons-httpclient.cgi

  - http://mirror.apache-kr.org/jakarta/commons/httpclient/binary/commons-httpclient-3.0.1.zip

)

 

commons-httpclient-3.0.1.zip 를 받아서 압축을 풀고, 

commons-httpclient-3.0.1.jar 를 CLASSPATH 에 추가하면 된다.

 

1-3. 추가 설정(Dependencies)

http://jakarta.apache.org/commons/httpclient/dependencies.html

 

Artifact ID  Type  Version  Scope  URL  Comment  

commons-codec jar 1.2  http://jakarta.apache.org/commons/codec/

                       http://jakarta.apache.org/site/downloads/downloads_commons-codec.cgi

commons-logging jar 1.0.4  http://jakarta.apache.org/commons/logging/   

junit jar 3.8.1 test  http://www.junit.org/  

 

 

#### 2. getMethod 사용 예제

=========================== GetSample.java =================================

package test.httpclient;

import java.io.FileOutputStream;

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;

// Get Method를 사용한 예제

public class GetSample {

    // 가져올 페이지 주소, 네이버 뉴스 속보

    private static String url =

        "http://news.naver.com/news/list.php";

    // 파일에 byte[] 저장

    public static void saveBytes(String filepath, byte[] byteData) throws Exception

    {

        FileOutputStream foStream = null;

        try {

            foStream = new FileOutputStream(filepath);

            foStream.write(byteData);

        } finally {

            try {
                foStream.close();
                foStream = null;
            } catch (Exception e) {}

        }

    }

    /**

     * @param args

     */

    public static void main(String[] args) {

        // HttpClient 생성

        HttpClient client = new HttpClient();

        // 요청 Method 지정

        HttpMethod method = new GetMethod(url);

        try {

            // QueryString 지정, 1.문자열

            url = url + "?mode=LSD&section_id=001&menu_id=001&view=1";

            // QueryString 지정, 2.NameValuePair 사용

            //   NameValuePair nvp1= new NameValuePair("mode","LSD");

            //   NameValuePair nvp2= new NameValuePair("section_id","001");

            //   NameValuePair nvp3= new NameValuePair("menu_id","001");

            //   NameValuePair nvp4= new NameValuePair("view","1");

            //   method.setQueryString(new NameValuePair[]{nvp1,nvp2, nvp3, nvp4});

            System.out.println("QueryString>>> " + method.getQueryString());

            // HTTP 요청 및 요청 결과

            int statusCode = client.executeMethod(method);

            // 요청 결과..

            if (statusCode == HttpStatus.SC_OK) {

                System.out.println("요청 성공");

                System.out.println("응답 HTML:\n" + method.getResponseBodyAsString());

                // 결과 저장

                GetSample.saveBytes("naver_news.html", method.getResponseBody());

            } else if ((statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||

                (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) ||

                (statusCode == HttpStatus.SC_SEE_OTHER) ||

                (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {

                System.out.println("Redirecte !!!");

                System.out.println("Redirect target: " + method.getResponseHeader("location").getValue());

            }

        } catch (Exception e) {

            e.printStackTrace();

            // Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

            // commons-logging.jar, commons-logging-api.jar 를 CLASSPATH에 추가한다.

            // Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/codec/DecoderException

            // commons-codec-1.3.jar 를 CLASSPATH에 추가한다.

        }

    }

}

 

=========================== GetSample.java =================================

 

 

#### 3. postMethod 사용

GetMethod 나 PostMethod 나 사용방법은 비슷합니다.

PostMethod method = new PostMethod("http://xx.com/ex_login_ok.php");

NameValuePair userid = new NameValuePair("nick", "aaaaa");

NameValuePair userpw = new NameValuePair("password", "bbbb");

method.setRequestBody(new NameValuePair[] {
    userid,
    userpw
});

client.executeMethod(method);

 

#### 4. Header 사용

헤더를 사용하기 위해서는 setRequestHeader() 를 이용하여 원하는 헤더를 정의해 주시면 됩니다.

String charset = null; // 기존 charset 사용

//String charset = "euc_kr"; // charset 지정

// 요청 헤더 설정

if (charset == null) {

    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");

} else {

    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + charset);

}

 

#### 5. Cookie 사용

아직 정리가 않되서.. 분량이 좀 많네요.^^;

찬찬히 정리하겠습니다.

 

#### Reference

1) 자카르타 프로젝트 HttpClient와 FileUpload 사용하기 

  - http://blog.empas.com/inter999/read.html?a=3271313&l=1&v=trackback

 

 

 

=================================

=================================

=================================

 

 

 



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

여기에서 설명할 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(newInputStreamReader(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 사용

3HttpClient 에서는 프로그램에서 어떻게 쿠키를 효과적으로 관리할수 있을지에 대한

방법을 제공한다아래 예제는 쿠키정보를 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

<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" value="Upload Files" name="Submit">

</form>

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 >
<%

        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());

          }

        }

%>
Upload Successful !!

(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 프로토콜을 사용해 커뮤니케이션을 하고자

하는 어떤 프로그램에서도 손쉽게 사용할수 있다는 걸 알수 있다.

좀더 세밀한 제어는 자카르타 홈페이지에 들어 매뉴얼을 참고하고 앞으로

진행할 프로젝트등에 유용하게 사용하기 바란다

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://blog.naver.com/kuhong1/8254360

 

All communication over the Internet happens using a standard set of protocols, such as File Transfer Protocol (FTP), Simple Mail Transfer Protocol (SMTP), Post Office Protocol (POP), Hypertext Transfer Protocol (HTTP), and so on. HTTP is one of the most popular of these protocols and is integral to the World Wide Web. It is also a protocol that many of today’s applications have to be aware of and use wisely. If a Java application has to interact using HTTP, the Commons HttpClient component can make things a bit easier. Using this component, you do not have to worry about all the technicalities of the protocol but just concern yourself with the various classes and methods provided by the HttpClient component. In this article you will have a look at the capabilities of the HttpClient component and also some hands-on examples.

You will also have a quick look at the FileUpload component, which simplifies file-upload tasks on the server side. Finally, you will work through an example where you use HttpClient and FileUpload together.

NOTE For all server-based examples in this article, I have used Tomcat version 4.0.6; however, you should not have any problems if you use another server that supports servlets and Java Server Page (JSP) technology.

Table 9-1 shows the details for the components covered in this article.

Table 9-1. Component Details

Name Version Package
HttpClient 2.0-rc1 org.apache.commons.httpclient
FileUpload 1.0 org.apache.commons.fileupload

Introducing HttpClient

HttpClient is an attempt to provide a simple Application Programming Interface (API) that Java developers can use to create code that communicates over HTTP. If you are developing a Web browser or just an application that occasionally needs some data from the Web, HttpClient can help you develop the client code that will communicate over HTTP. As the name suggests, HttpClient is meant only for HTTP client code and cannot be used to, say, develop a server that processes HTTP requests.

I recommend you use HttpClient instead of using the java.net classes because HttpClient is easier to work with, it supports some HTTP features that java.net does not, and it has a vibrant community backing it. Visit http://www.nogoop.com/product_16.html#compare to compare HttpClient, java.net, and a couple of other APIs.

With a number of Commons components, the Javadocs are the only real documentation that exists. However, with HttpClient some good documentation exists beyond the Javadocs. A short tutorial at http://jakarta.apache.org/commons/httpclient/tutorial.html can get you started with HttpClient.

These are some of the important features of HttpClient:

  • Implements HTTP versions 1.0 and 1.1
  • Implements all HTTP methods, such as GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE
  • Supports communication using HTTPS and connections through HTTP proxies
  • Supports authentication using Basic, Digest, and NT LAN Manager (NTLM) methods
  • Handles cookies

You will now see the various elements of the HttpClient component and how they fall into place to get you talking over HTTP.

Using HttpClient

HttpClient uses the Commons Logging component, so the only dependency for HttpClient to work properly is that the commons-logging component Java Archive (JAR) file be present. Using HttpClient to handle most requirements is fairly simple. You just need to understand a few key classes and interfaces. The following sections present a simple example of sending a GET request and then explain the classes that play a role in how the example works.

Using the GET Method

The GET method is the most common method used to send an HTTP request. Every time you click a hyperlink, you send an HTTP request using the GET method. You will now see an example of sending a GET request using HttpClient based Java code. The code in Listing 9-1 sends a GET request to the URL http://localhost:8080/validatorStrutsApp/userInfo.do and has three request parameters, firstnamelastname, and email.

 

Listing 9-1. HttpClientTrial
package com.commonsbook.chap9;
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();
        }
    }
}

 

The output on executing this piece of code will depend on the response you get to your GET request.

The following steps take place in the class SubmitHttpForm to invoke the URL specified, including passing the three parameters as part of the query string, displaying the response, and writing the response to a file:

  1. You first need to instantiate the HttpClient, and because you have specified no parameters to the constructor, by default the org.apache.commons.httpclient.SimpleHttpConnectionManager class is used to create a new HttpClient. To use a different ConnectionManager, you can specify any class implementing the interface org.apache.commons.httpclient.HttpConnectionManager as a parameter to the constructor. You can use the MultiThreadedHttpConnectionManager connection manager if more than one thread is likely to use the HttpClient. The code would then be new HttpClient(new MultiThreadedHttpConnectionManager()).
  2. Next you create an instance of HttpMethod. Because HttpClient provides implementations for all HTTP methods, you could very well have chosen an instance of PostMethod instead of GetMethod. Because you are using an HttpMethod reference and not a reference of an implementation class such as GetMethod or PostMethod, you intend to use no special features provided by implementations such as GetMethod or PostMethod.
  3. You define name/value pairs and then set an array of those name/value pairs into the query string.
  4. Once the groundwork is complete, you execute the method using the HttpClient instance you created in step 1. The response code returned is based on the success or failure of the execution.
  5. You get the response body both as a string and as a byte array. The response is printed to the console and also written to a file named donepage.html.NOTE The class org.apache.commons.httpclient.HttpStatus defines static int variables that map to HTTP status codes.

In this example, you can see how easily you can fire a request and get a response over HTTP using the HttpClient component. You might have noted that writing such code has a lot of potential to enable testing of Web applications quickly and to even load test them. This has led to HttpClient being used in popular testing framework such as Jakarta Cactus, HTMLUnit, and so on. You can find in the documentation a list of popular applications that use HttpClient.

You used the GET method to send name/value pairs as part of a request. However, the GET method cannot always serve your purpose, and in some cases using the POST method is a better option.

Using the POST Method

Listing 9-2 shows an example where you enclose an Extensible Markup Language (XML) file within a request and send it using the POST method to a JSP named GetRequest.jsp. The JSP will just print the request headers it receives. These headers will show if the request got across properly.

 

Listing 9-2. Sending an XML File Using the POST Method
package com.commonsbook.chap9;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class PostAFile {
    private static String url =
         "http://localhost:8080/HttpServerSideApp/GetRequest.jsp";

    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("students.xml");
        System.out.println("File Length = " + f.length());

        postMethod.setRequestBody(new FileInputStream(f));
        postMethod.setRequestHeader("Content-type",
            "text/xml; charset=ISO-8859-1");

        int statusCode1 = client.executeMethod(postMethod);

        System.out.println("statusLine>>>" + postMethod.getStatusLine());
        postMethod.releaseConnection();
    }
}

 

In Listing 9-2, I have stated the URL for GetRequest.jsp using a server I am running locally on port 8080. This URL will vary based on the server where the JSP is being maintained. In this example, you create an instance of the classes HttpClient and PostMethod. You set the connection timeout for the HTTP connection to 3,000 milliseconds and then set an XML file into the request body. I am using a file named students.xml however, the contents of the file are not relevant to the example, and you could very well use any other file. Because you are sending an XML file, you also set the Content-Type header to state the format and the character set.GetRequest.jsp contains only a scriptlet that prints the request headers. The contents of the JSP are as follows:

<%
        java.util.Enumeration e= request.getHeaderNames();
        while (e.hasMoreElements()) {
          String headerName=(String)e.nextElement();
          System.out.println(headerName +" = "+request.getHeader(headerName));
        }
%>

Upon executing the class PostAFile, the JSP gets invoked, and the output displayed on the server console is as follows:

content-type = text/xml; charset=ISO-8859-1
user-agent = Jakarta Commons-HttpClient/2.0rc1
host = localhost:8080
content-length = 279

The output shown on the console where the PostAFile class was executed is as follows:

File Length = 279
statusLine>>>HTTP/1.1 200 OK

Note that the output on the server shows the content length as 279 (bytes), the same as the length of the file students.xml that is shown on the application console. Because you are not invoking the JSP using any browser, the User-Agent header that normally states the browser specifics shows the HttpClient version being used instead.

NOTE In this example, you sent a single file over HTTP. To upload multiple files, the MultipartPostMethod class is a better alternative. You will look at it later in the “Introducing FileUpload” section.

Managing Cookies

HttpClient provides cookie management features that can be particularly useful to test the way an application handles cookies. Listing 9-3 shows an example where you use HttpClient to add a cookie to a request and also to list details of cookies set by the JSP you invoke using the HttpClient code.

The HttpState class plays an important role while working with cookies. The HttpState class works as a container for HTTP attributes such as cookies that can persist from one request to another. When you normally surf the Web, the Web browser is what stores the HTTP attributes.

Listing 9-3. CookiesTrial.java
package com.commonsbook.chap9;
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();
    }
}

In Listing 9-3, you use the HttpState instance to store a new cookie and then associate this instance with the HttpClient instance. You then invoke CookieMgt.jsp. This JSP is meant to print the cookies it finds in the request and then add a cookie of its own. The JSP code is as follows:

<%
        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"));
%>

CAUTION HttpClient code uses the classorg.apache.commons.httpclient.Cookie, and JSP and servlet code uses the class javax.servlet.http.Cookie.

The output on the application console upon executing the CookiesTrial class and invoking CookieMgt.jsp is as follows:

statusLine>>>HTTP/1.1 200 OK

CookieName=ABCD
Value=00000
Domain=127.0.0.1

CookieName=XYZ
Value=12345
Domain=127.0.0.1

CookieName=JSESSIONID
Value=C46581331881A84483F0004390F94508
Domain=127.0.0.1

In this output, note that although the cookie named ABCD has been created from CookiesTrial, the other cookie named XYZ is the one inserted by the JSP code. The cookie named JSESSIONID is meant for session tracking and gets created upon invoking the JSP. The output as displayed on the console of the server when the JSP is executed is as follows:

ABCD = 00000

This shows that when CookieMgt.jsp receives the request from the CookiesTrial class, the cookie named ABCD was the only cookie that existed. The sidebar “HTTPS and Proxy Servers” shows how you should handle requests over HTTPS and configure your client to go through a proxy.

HTTPS and Proxy Servers

Using HttpClient to try out URLs that involve HTTPS is the same as with ordinary URLs. 
Just state https://… as your URL, and it should work fine. You only need to have Java 
Secure Socket Extension (JSSE) running properly on your machine. JSSE ships as a part of 
Java Software Development Kit (JSDK) 1.4 and higher and does not require any separate 
download and installation.

If you have to go through a proxy server, introduce the following piece of code. 
Replace PROXYHOST with the host name and replace 9999 with the port number for your 
proxy server:

HttpClient client = new HttpClient();
HostConfiguration hConf= client.getHostConfiguration();
hConf.setProxy("PROXYHOST ", 9999);
If you also need to specify a username password for the proxy, 
you can do this using the setProxyCredentials method of the class HttpState. 
This method takes a Credentials object as a parameter. Credentials is a marker 
interface that has no methods and has a single implementationUsernamePasswordCredentials. 
You can use this class to create aCredentials object that holds the username and password 
required for Basic authentication.

You will now see the HttpClient component’s capability to use MultipartPostMethod to upload multiple files. You will look at this in tandem with the Commons FileUpload component. This Commons component is specifically meant to handle the server-side tasks associated with file uploads.

Introducing FileUpload

The FileUpload component has the capability of simplifying the handling of files uploaded to a server. Note that the FileUpload component is meant for use on the server side; in other words, it handles where the files are being uploaded to—not the client side where the files are uploaded from. Uploading files from an HTML form is pretty simple; however, handling these files when they get to the server is not that simple. If you want to apply any rules and store these files based on those rules, things get more difficult.

The FileUpload component remedies this situation, and in very few lines of code you can easily manage the files uploaded and store them in appropriate locations. You will now see an example where you upload some files first using a standard HTML form and then using HttpClient code.

Using HTML File Upload

The commonly used methodology to upload files is to have an HTML form where you define the files you want to upload. A common example of this HTML interface is the Web page you encounter when you want to attach files to an email while using any of the popular Web mail services.

In this example, you will create a simple HTML page where you provide for three files to be uploaded. Listing 9-4 shows the HTML for this page. Note that the enctype attribute for the form has the value multipart/form-data, and the input tag used is of type file. Based on the value of the action attribute, on form submission, the data is sent to ProcessFileUpload.jsp.

Listing 9-4. UploadFiles.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>

You can use a servlet to handle the file upload. I have used JSP to minimize the code you need to write. The task that the JSP has to accomplish is to pick up the files that are sent as part of the request and store these files on the server. In the JSP, instead of displaying the result of the upload in the Web browser, I have chosen to print messages on the server console so that you can use this same JSP when it is not invoked through an HTML form but by using HttpClient-based code.

Listing 9-5 shows the JSP code. Note the code that checks whether the item is a form field. This check is required because the Submit button contents are also sent as part of the request, and you want to distinguish between this data and the files that are part of the request. You have set the maximum file size to 1,000,000 bytes using the setSizeMax method.

 

Listing 9-5. 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>

CAUTION With FileUpload 1.0 I found that when the form was submitted using Opera version 7.11, the getName method of the class FileItem returns just the name of the file. However, if the form is submitted using Internet Explorer 5.5, the filename along with its entire path is returned by the same method. This can cause some problems.

To run this example, you can use any three files, as the contents of the files are not important. Upon submitting the form using Opera and uploading three random XML files, the output I got on the Tomcat server console was as follows:

Content Type =multipart/form-data; boundary=----------rz7ZNYDVpN1To8L73sZ6OE

NAME: academy.xml
SIZE: 951
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academy.xml

NAME: academyRules.xml
SIZE: 1211
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academyRules.xml

NAME: students.xml
SIZE: 279
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\students.xml
Field =Submit
However, when submitting this same form using Internet Explorer 5.5, the output on the server console was as follows:
Content Type =multipart/form-data; boundary=---------------------------7d3bb1de0
2e4

NAME: D:\temp\academy.xml
SIZE: 951
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\D:\temp\academy.xml

The browser displayed the following message: “The requested resource (D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\D:\temp\academy.xml (The filename, directory name, or volume label syntax is incorrect)) is not available.”

This contrasting behavior on different browsers can cause problems. One workaround that I found in an article at http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html is to first create a file reference with whatever is supplied by the getName method and then create a new file reference using the name returned by the earlier file reference. Therefore, you can insert the following code to have your code work with both browsers (I wonder who the guilty party is…blaming Microsoft is always the easy way out)

File tempFileRef  = new File(fi.getName());
File fNew = new File(application.getRealPath("/"),tempFileRef.getName());

In this section, you uploaded files using a standard HTML form mechanism. However, often a need arises to be able to upload files from within your Java code, without any browser or form coming into the picture. In the next section, you will look at HttpClient-based file upload.

Using HttpClient-Based FileUpload

Earlier in the article you saw some of the capabilities of the HttpClient component. One capability I did not cover was its ability to send multipart requests. In this section, you will use this capability to upload a few files to the same JSP that you used for uploads using HTML.

The class org.apache.commons.httpclient.methods.MultipartPostMethod provides the multipart method capability to send multipart-encoded forms, and the packageorg.apache.commons.httpclient.methods.multipart has the support classes required. Sending a multipart form using HttpClient is quite simple. In the code in Listing 9-6, you send three files to ProcessFileUpload.jsp.

Listing 9-6. HttpMultiPartFileUpload.java
package com.commonsbook.chap9;
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();
    }
}

In this code, you just add the files as parameters and execute the method. TheProcessFileUpload.jsp file gets invoked, and the output is as follows:

Content Type =multipart/form-data; boundary=----------------31415926535897932384
6

NAME: students.xml
SIZE: 279
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\students.xml

NAME: academy.xml
SIZE: 951
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academy.xml

NAME: academyRules.xml
SIZE: 1211
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academyRules.xml

Thus, file uploads on the server side become quite a simple task if you are using the Commons FileUpload component.

Summary

In this article, you saw the HttpClient and FileUpload components. Although HttpClient can be useful in any kind of applications that use HTTP for communication, the FileUpload component has a much more specific scope. One important plus for HttpClient is the existence of a decent user guide and tutorial. The FileUpload component can be just what you are looking for if you are wondering what to use and how to manage files uploaded through your application.

 

 

 

=================================

=================================

=================================

 

 

 

 

반응형


관련글 더보기

댓글 영역