天天看点

Java CookBook Learning Day3rd--HTTP (by Tim O'Brien)

1.6.Making an HTTP POST Request

  1.6.1. Problem

  You need to supply parameters to a script or servlet using HTTP POST.

  1.6.2 Solution

   Create a PostMethod and call set Parameter( ) or addParameter( ) before you execute the method. The PostMethod will send a request with a  content-Type header of application/x-www-form-urlencoded, and the parameters will be sent in the rquest body. The following example demonstrates the use of PostMethod to send parameters:

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.NameValuePair;

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

HttpClient client = new HttpClient( );

//Create POST method

String url =  "http://www.discursive.com/cgi-bin/jccook/param_list.cgi";

PostMethod method = new PostMethod( url );

//set parameters on POST

method.setParameter ("test1", "Hello World");

method.addParameter("test2", "This is a Form Submission");

method.addParameter("Blah", "Whoop");

method.addParameter(new NameValuePair("Blah", "Whoop2");

//Execute and print response

client.executeMethod(method);

String reponse = method.getResponseBodyAsString( );

System.out.println(response);

method.releaseConnection( );

  The param_list.cgi CGI script echoes all parameters received, and from the following output, you can see that three parameters were supplied to this script:

These are the parameters I received:

test1:

Hello World

test2:

This is a Form Submission

Blah:

Whoop

Whoop2

  1.6.3 Solution

  The previous example sent the parameters in the request body. The request created by the previous example is shown below:

POST /cgi-bin/jccook/param_list.cgi HTTP/1.1[\r][\n]

User-Agent: Jakarta Commons-HttpClient/3.0final[\r][\n]

Host: www.discursive.com[\r][\n]

Content-Length: 72[\r][\n]

Content-Type: application/x-www-form-urlencoded[\r][\n]

[\r][\n]

test1=Hello+World&test2=This+is+a+Form+Submission&Blah=Whoop&Blah=Whoop2

  This output was produced by turning on wire debugging for HttpClient, as described in Recipe 11.6.

  The first line specifies the HTTP method, the request path, and the protocol. The second line identifies this client as HttpClient Version 3.0. The third line specifies the request host and is used by servers serving many different virtual hosts using one IP address. The fourth line states that the request body is exactly 72 bytes, and the Content-Type header defines the request body as being a series of URL-encoded parameters. The parameters are passed in one line as name1=value1&name2=value&, etc.

 1.7. Sending POST Data from a File

 1.7.1 Problem

  You need to send the data from a file in an HTTP POST request.

  1.7.1 Solution

  Create a PostMethod, create a File Object, and call setRequestBody( ) and setRequestContentLength( ) on the method before it is executed. The PostMethod will send a request with a Content-Length header, which reflects the size of the file sent in the request body. The following example demonstrates the use of PostMethod to send data from a file in a request body:

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.HttpException;

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

HttpClient client = new HttpClient( );

//Create POST method

String weblinkURL="http://ats.nist.gov/cgi-bin/cgi.tcl/echo.cgi";

PostMethod method = new PostMethod( weblinkURL);

File file = new File("project.xml");

method.setRequestBody(new FileInputStream( file ) );

method.setRequestContentLength((int)file.length());

//Execute and print response

client.executeMethod( method );

String reponse = method.getResponseBodyAsString( );

System.out.println(reponse);

method.releaseConnection( );

The previous example hits a CGI script, which echoes the contents of the request body. When this example is executed, the response body is printed with the contents of the file that was uploaded in an HTTP POST request.

  1.7.3.Discussion

  This recipe sets the request body of  an HTTP POST directly by passing a File Object to method.setRequestBody( ); In addition to accepting a File object, setRequestBody( ) can accept an InputStream or a String. Any time a request body is populated, the Content-Length header must be set to reflect the size of request body by calling method.setRequestContentLength( ). The previous recipe sent parameters in an HTTP POST request body by calling setParameter( ) and addParameter( ), and the Content-Length and Content-Type headers are automatically populated when the method is executed. In this example, the Content-Type header is not sent with the request as the content can be any arbitrary textual or binary data.

 1.8. Uploading Files with a Multipart POST

 1.8.1.Problem

  You need to upload a file or a set of files with an HTTP multipart POST.

  1.8.2 Solution

  Create a MultipartPostMethod and add File objects as parameters using addParameter( ) and addPart( ). The MultiPartPostMethod creates a request with a  Content-Type header of multipart/form-data, and each part is separated by a boundary. The following example sends two files in an HTTP multipart POST:

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.Excepiton;

import org.apache.commons.httpclient.methods.MultipartPostMethod;

import org.apache.commons.httpclient.multipart.FilePart;

HttpClient client = new HttpClient;

//Create POST Method// Create POST method

String weblintURL = "http://ats.nist.gov/cgi-bin/cgi.tcl/echo.cgi";

MultipartPostMethod method = new MultipartPostMethod (weblinkURL);

File file = new File ("data", "test.txt");

File file2 = new File( "data", "sample.txt");

method.addParameter("test.txt",file);

method.addPart(new FilePart("sample.txt", file2,"text/plain","ISO-8859-1"));

//Execute and print reponse

client.executeMethod( method);

String response = method.getResponseBodyAsString( );

System.out.println( response);

method.releaseConneciton( );

  Two File objects are added to the MultipartPostMethod using two different methods. The first method, addParameter( ), adds a File object and sets the file name to test.txt. The second method, addPart(), adds a FilePart object to the MultipartPostMethod. Both files are sent in the request separated by a part boundary, and the script echoes the location and type of both files on the server:

<h3>Form input</h3>

<pre>

sample.txt = /tmp/CGI14480.4 sample.txt {text/plain; charset=ISO-8859-1}

test.txt = /tmp/CGI14480.2 test.txt {application/octet-stream;

charset=ISO-8859-1}

</pre>

   1.8.3 Discussion

   Adding a part as a FilePart object allows you to specify the Multipurpose Internet Main Extension(MIME) type and the character set of the part. In this example, the sample.txt file is addedd with a text/plain MIME type and ISO-8850-1 character set. If a File is added to the method using addParameter( ) or setParameter( ), it is sent with the default application/octet-stream type and the default ISO-8859-1 characer set.

  When HttpClient executes the MultipartPostMethod created in the previous example, the following request is sent to the server. The Content-Type header is multipart/form-data, and an arbitrary boundary is created to delineate multiple parts being sent in the request:

POST /cgi-bin/cgi.tcl/echo.cgi HTTP/1.1

User-Agent: Jakarta Commons-HttpClient/3.0final

Host: ats.nist.gov

Content-Length: 498

Content-Type: multipart/form-data; boundary=----------------31415926535

8979323846

------------------314159265358979323846

Content-Disposition: form-data; name=test.txt; filename=test.txt

Content-Type: application/octet-stream; charset=ISO-8859-1

Content-Transfer-Encoding: binary

This is a test.

------------------314159265358979323846

Content-Disposition: form-data; name=sample.txt; filename=sample.txt

Content-Type: text/plain; charset=ISO-8859-1

Content-Transfer-Encoding: binary

This is a sample

------------------314159265358979323846--    

Each part contains a Content-Disposition header to name the part and a Content-Type header to classify the part with a MIME type and character set.

继续阅读