KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > oreilly > servlet > HttpMessage


1 // Copyright (C) 1998-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>.
2
// All rights reserved. Use of this class is limited.
3
// Please see the LICENSE for more information.
4

5 package com.oreilly.servlet;
6
7 import java.io.*;
8 import java.net.*;
9 import java.util.*;
10
11 import com.knowgate.misc.Base64Encoder;
12
13 /**
14  * A class to simplify HTTP applet-server communication. It abstracts
15  * the communication into messages, which can be either GET or POST.
16  * <p>
17  * It can be used like this:
18  * <blockquote><pre>
19  * URL url = new URL(getCodeBase(), "/servlet/ServletName");
20  * &nbsp;
21  * HttpMessage msg = new HttpMessage(url);
22  * &nbsp;
23  * // Parameters may optionally be set using java.util.Properties
24  * Properties props = new Properties();
25  * props.put("name", "value");
26  * &nbsp;
27  * // Headers, cookies, and authorization may be set as well
28  * msg.setHeader("Accept", "image/png"); // optional
29  * msg.setCookie("JSESSIONID", "9585155923883872"); // optional
30  * msg.setAuthorization("guest", "try2gueSS"); // optional
31  * &nbsp;
32  * InputStream in = msg.sendGetMessage(props);
33  * </pre></blockquote>
34  * <p>
35  * This class is loosely modeled after the ServletMessage class written
36  * by Rod McChesney of JavaSoft.
37  *
38  * @author <b>Jason Hunter</b>, Copyright &#169; 1998
39  * @version 1.3, 2000/10/24, fixed headers NPE bug
40  * @version 1.2, 2000/10/15, changed uploaded object MIME type to
41  * application/x-java-serialized-object
42  * @version 1.1, 2000/06/11, added ability to set headers, cookies,
43                              and authorization
44  * @version 1.0, 1998/09/18
45  */

46 public class HttpMessage {
47
48   URL servlet = null;
49   Hashtable headers = null;
50
51   /**
52    * Constructs a new HttpMessage that can be used to communicate with the
53    * servlet at the specified URL.
54    *
55    * @param servlet the server resource (typically a servlet) with which
56    * to communicate
57    */

58   public HttpMessage(URL servlet) {
59     this.servlet = servlet;
60   }
61
62   /**
63    * Performs a GET request to the servlet, with no query string.
64    *
65    * @return an InputStream to read the response
66    * @exception IOException if an I/O error occurs
67    */

68   public InputStream sendGetMessage() throws IOException {
69     return sendGetMessage(null);
70   }
71
72   /**
73    * Performs a GET request to the servlet, building
74    * a query string from the supplied properties list.
75    *
76    * @param args the properties list from which to build a query string
77    * @return an InputStream to read the response
78    * @exception IOException if an I/O error occurs
79    */

80   public InputStream sendGetMessage(Properties args) throws IOException {
81     String JavaDoc argString = ""; // default
82

83     if (args != null) {
84       argString = "?" + toEncodedString(args);
85     }
86     URL url = new URL(servlet.toExternalForm() + argString);
87
88     // Turn off caching
89
URLConnection con = url.openConnection();
90     con.setUseCaches(false);
91
92     // Send headers
93
sendHeaders(con);
94
95     return con.getInputStream();
96   }
97
98   /**
99    * Performs a POST request to the servlet, with no query string.
100    *
101    * @return an InputStream to read the response
102    * @exception IOException if an I/O error occurs
103    */

104   public InputStream sendPostMessage() throws IOException {
105     return sendPostMessage(null);
106   }
107
108   /**
109    * Performs a POST request to the servlet, building
110    * post data from the supplied properties list.
111    *
112    * @param args the properties list from which to build the post data
113    * @return an InputStream to read the response
114    * @exception IOException if an I/O error occurs
115    */

116   public InputStream sendPostMessage(Properties args) throws IOException {
117     String JavaDoc argString = ""; // default
118
if (args != null) {
119       argString = toEncodedString(args); // notice no "?"
120
}
121
122     URLConnection con = servlet.openConnection();
123
124     // Prepare for both input and output
125
con.setDoInput(true);
126     con.setDoOutput(true);
127
128     // Turn off caching
129
con.setUseCaches(false);
130
131     // Work around a Netscape bug
132
con.setRequestProperty("Content-Type",
133                            "application/x-www-form-urlencoded");
134
135     // Send headers
136
sendHeaders(con);
137
138     // Write the arguments as post data
139
DataOutputStream out = new DataOutputStream(con.getOutputStream());
140     out.writeBytes(argString);
141     out.flush();
142     out.close();
143
144     return con.getInputStream();
145   }
146
147   /**
148    * Performs a POST request to the servlet, uploading a serialized object.
149    * <p>
150    * The servlet can receive the object in its <tt>doPost()</tt> method
151    * like this:
152    * <pre>
153    * ObjectInputStream objin =
154    * new ObjectInputStream(req.getInputStream());
155    * Object obj = objin.readObject();
156    * </pre>
157    * The type of the uploaded object can be determined through introspection.
158    *
159    * @param obj the serializable object to upload
160    * @return an InputStream to read the response
161    * @exception IOException if an I/O error occurs
162    */

163   public InputStream sendPostMessage(Serializable obj) throws IOException {
164     URLConnection con = servlet.openConnection();
165
166     // Prepare for both input and output
167
con.setDoInput(true);
168     con.setDoOutput(true);
169
170     // Turn off caching
171
con.setUseCaches(false);
172
173     // Set the content type to be application/x-java-serialized-object
174
con.setRequestProperty("Content-Type",
175                            "application/x-java-serialized-object");
176
177     // Send headers
178
sendHeaders(con);
179
180     // Write the serialized object as post data
181
ObjectOutputStream out = new ObjectOutputStream(con.getOutputStream());
182     out.writeObject(obj);
183     out.flush();
184     out.close();
185
186     return con.getInputStream();
187   }
188
189   /**
190    * Sets a request header with the given name and value. The header
191    * persists across multiple requests. The caller is responsible for
192    * ensuring there are no illegal characters in the name and value.
193    *
194    * @param name the header name
195    * @param value the header value
196    */

197   public void setHeader(String JavaDoc name, String JavaDoc value) {
198     if (headers == null) {
199       headers = new Hashtable();
200     }
201     headers.put(name, value);
202   }
203
204   // Send the contents of the headers hashtable to the server
205
private void sendHeaders(URLConnection con) {
206     if (headers != null) {
207       Enumeration headerenum = headers.keys();
208       while (headerenum.hasMoreElements()) {
209         String JavaDoc name = (String JavaDoc) headerenum.nextElement();
210         String JavaDoc value = (String JavaDoc) headers.get(name);
211         con.setRequestProperty(name, value);
212       }
213     }
214   }
215
216   /**
217    * Sets a request cookie with the given name and value. The cookie
218    * persists across multiple requests. The caller is responsible for
219    * ensuring there are no illegal characters in the name and value.
220    *
221    * @param name the header name
222    * @param value the header value
223    */

224   public void setCookie(String JavaDoc name, String JavaDoc value) {
225     if (headers == null) {
226       headers = new Hashtable();
227     }
228     String JavaDoc existingCookies = (String JavaDoc) headers.get("Cookie");
229     if (existingCookies == null) {
230       setHeader("Cookie", name + "=" + value);
231     }
232     else {
233       setHeader("Cookie", existingCookies + "; " + name + "=" + value);
234     }
235   }
236
237   /**
238    * Sets the authorization information for the request (using BASIC
239    * authentication via the HTTP Authorization header). The authorization
240    * persists across multiple requests.
241    *
242    * @param name the user name
243    * @param name the user password
244    */

245   public void setAuthorization(String JavaDoc name, String JavaDoc password) {
246     String JavaDoc authorization = Base64Encoder.encode(name + ":" + password);
247     setHeader("Authorization", "Basic " + authorization);
248   }
249
250   /*
251    * Converts a properties list to a URL-encoded query string
252    */

253   private String JavaDoc toEncodedString(Properties args) {
254     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
255     Enumeration names = args.propertyNames();
256     while (names.hasMoreElements()) {
257       String JavaDoc name = (String JavaDoc) names.nextElement();
258       String JavaDoc value = args.getProperty(name);
259       buf.append(URLEncoder.encode(name) + "=" + URLEncoder.encode(value));
260       if (names.hasMoreElements()) buf.append("&");
261     }
262     return buf.toString();
263   }
264 }
265
Popular Tags