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 jsp servlet ejb 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 jsp servlet ejb Server Page (JSP) technology.
Table 9-1 Shows The Details for The Components Covered in This Article.
Table 9-1. Component Details
NameversionPackageHttpClient2.0-rc1org.apache.commons.httpclientfileupload1.0org.apache.commons.fileupload
Introducing httpclient
HttpClient is an attempt to provide a simple Application Programming Interface (API) that jsp servlet ejb 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 can not be used to, say, develop a server that processes HTTP requests.I recommend you use HttpClient instead of using the jsp servlet ejb .net classes because HttpClient is easier to work with, it supports some HTTP features that jsp servlet ejb .net does not, and it has a vibrant community backing it. Visit http://www.nogoop.com/product_16 .html # Compare to Compare HttpClient, JSP Servlet EJB .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 the fall int ounce 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 jsp servlet ejb 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 Sending A Get Request and the 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 jsp servlet ejb 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, FirstName, Lastname, And Email.
Listing 9-1. HttpClientTrial
Package com.Commonsbook.chap9;
Import JSP Servlet EJB .IO.FileoutputStream;
Import JSP servlet ejb .io.ioException;
Import org.apache.commons.httpclient. *;
Import org.apache.commons.httpclient.methods.getMethod;
Public class submittpform {
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 int t querystring
NameValuePair NVP1 = New NameValuePair ("Firstname", "FNAME");
NameValuePair NVP2 = New NameValuePair ("Lastname", "Lname");
NameValuePair NVP3 = New NameValuePair ("email", "email@emil.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:
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 ( )). 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. You define name / value pairs and then set an array of those name / value pairs into the query string. 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. 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 cots.
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 JSP servlet ejb .io.file;
Import JSP servlet ejb .io.fileinputstream;
Import JSP servlet ejb .io.ioException;
Public class postafile {
Private static string URL =
"http: // localhost: 8080 / httpserversideapp / getRequest.jsp";
Public static void main (string [] args) throws oException {
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:
<%
JSP servlet ejb .util.Enumeration E = Request.getHeadernames ();
While (E.haASMoreElements ()) {
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 SFLLOWS:
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 Normal State 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 casses 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 stiled in the httpState for this instance of httpclient
Cookie [] cookies = httpclient.getState (). GetCookies ();
For (int i = 0; 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 System.out.println (cookies [i] .Getname () "=" cookies [i] .getValue ()); // Add a new cookie Response.addcookie (New Cookie ("XYZ", "12345"); %> . 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 = c4658131881a84483f0004390f94508 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 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 jsp servlet ejb Secure Socket Extension ( JSSE) running properly on your machine. JSSE ships as a part of jsp servlet ejb 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 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 implementation UsernamePasswordCredentials. You can use this class to create a credentials object what 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 sample to processfileupload.jsp. Listing 9-4. UPLOADFILES.HTML
HEAD>
Upload Files