KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > plankton > http > HttpRequester


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: HttpRequester.java,v 1.6 2004/02/01 05:16:28 christianc Exp $
19  */

20 package org.enhydra.barracuda.plankton.http;
21
22 import java.io.*;
23 import java.net.*;
24 import java.text.*;
25 import java.util.*;
26 import javax.servlet.http.*;
27
28 import org.enhydra.barracuda.plankton.data.Base64;
29
30 /**
31  * This class encapsulates access to/from a URL via both POST and GET methods.
32  * To use, simply set the URL, the method (POST/GET), and the params. If you're
33  * using get, the params are optional (they can be included as part of the URL).
34  * Also note that you can pass a username and password if you need to do basic
35  * authentication. This class also now supports cookies, thanks to Shawn Wilson
36  * [shawnw@atmreports.com] - look at the sample code down in the main method for
37  * an example of how to use it (basically, you just use the requestor to access a
38  * URL, thereby getting the cookie, and then you re-use the requestor to access
39  * any other URLs which depend on that cookie).
40  *
41  * Refer to the source for this class (main method) to see an example of
42  * how you would use this class for both POST and GET methods:
43  */

44 public class HttpRequester {
45
46     public static final String JavaDoc POST = "POST";
47     public static final String JavaDoc GET = "GET";
48
49     protected URL url = null;
50     protected String JavaDoc method = GET;
51     protected Map props = null;
52     protected HttpOutputWriter outputWriter = null;
53     protected String JavaDoc user = null;
54     protected String JavaDoc password = null;
55     protected boolean authenticate = false;
56     protected boolean acceptCookies = true; //saw_121102.2
57
protected List cookies = null; //saw_121102.2
58

59     protected OutputStream outStream = null;
60     protected InputStream inStream = null;
61     protected BufferedReader in = null;
62     protected URLConnection conn = null; //csc_010404_1
63

64
65     /**
66      * Set the Request. This is a convenience method to encapsulate
67      * calls to setUrl, setMethod, and setParams all in one fell swoop.
68      *
69      * @param iurl the URL we wish to access
70      * @param imethod the method we wish to use (either GET or POST)
71      * @param iprops the Map contains our key-value URL parameter pairs.
72      * If the value is a Set, the resulting URL will contain a key-value
73      * mapping for each entry in the Set.
74      * @throws MalformedURLException
75      */

76     public void setRequest(String JavaDoc iurl, String JavaDoc imethod, Map iprops) throws MalformedURLException {
77         setRequest(iurl, imethod, iprops, null);
78     }
79
80     /**
81      * Set the Request. This is a convenience method to encapsulate
82      * calls to setUrl, setMethod, and setParams all in one fell swoop.
83      *
84      * @param iurl the URL we wish to access
85      * @param imethod the method we wish to use (either GET or POST)
86      * @param iprops the Map contains our key-value URL parameter pairs.
87      * If the value is a Set, the resulting URL will contain a key-value
88      * mapping for each entry in the Set.
89      * @throws MalformedURLException
90      */

91     public void setRequest(URL iurl, String JavaDoc imethod, Map iprops) throws MalformedURLException {
92         setRequest(iurl, imethod, iprops, null);
93     }
94
95     /**
96      * Set the Request. This is a convenience method to encapsulate
97      * calls to setUrl, setMethod, and setParams all in one fell swoop.
98      *
99      * @param iurl the URL we wish to access
100      * @param imethod the method we wish to use (either GET or POST)
101      * @param iprops the Map contains our key-value URL parameter pairs.
102      * If the value is a Set, the resulting URL will contain a key-value
103      * mapping for each entry in the Set.
104      * @param ioutputWriter the HttpOutputWriter we wish to write to
105      * @throws MalformedURLException
106      */

107     public void setRequest(String JavaDoc iurl, String JavaDoc imethod, Map iprops, HttpOutputWriter ioutputWriter) throws MalformedURLException {
108         setRequest(iurl, imethod, iprops, null, null, null);
109     }
110
111     /**
112      * Set the Request. This is a convenience method to encapsulate
113      * calls to setUrl, setMethod, and setParams all in one fell swoop.
114      *
115      * @param iurl the URL we wish to access
116      * @param imethod the method we wish to use (either GET or POST)
117      * @param iprops the Map contains our key-value URL parameter pairs.
118      * If the value is a Set, the resulting URL will contain a key-value
119      * mapping for each entry in the Set.
120      * @param ioutputWriter the HttpOutputWriter we wish to write to
121      * @throws MalformedURLException
122      */

123     public void setRequest(URL iurl, String JavaDoc imethod, Map iprops, HttpOutputWriter ioutputWriter) throws MalformedURLException {
124         setRequest(iurl, imethod, iprops, null, null, null);
125     }
126
127     /**
128      * Set the Request. This is a convenience method to encapsulate
129      * calls to setUrl, setMethod, and setParams all in one fell swoop.
130      *
131      * @param iurl the URL we wish to access
132      * @param imethod the method we wish to use (either GET or POST)
133      * @param iprops the Map contains our key-value URL parameter pairs.
134      * If the value is a Set, the resulting URL will contain a key-value
135      * mapping for each entry in the Set.
136      * @param iuser the user named required to connect
137      * @param ipwd the password named required to connect
138      * @param ioutputWriter the HttpOutputWriter we wish to write to
139      * @throws MalformedURLException
140      */

141     public void setRequest(String JavaDoc iurl, String JavaDoc imethod, Map iprops, String JavaDoc iuser, String JavaDoc ipwd, HttpOutputWriter ioutputWriter) throws MalformedURLException {
142         if (iurl!=null) setUrl(iurl);
143         if (imethod!=null) setMethod(imethod);
144         if (iprops!=null) setParams(iprops);
145         if (iuser!=null) setUser(iuser);
146         if (ipwd!=null) setPassword(ipwd);
147         if (ioutputWriter!=null) setOutputWriter(ioutputWriter);
148     }
149
150     /**
151      * Set the Request. This is a convenience method to encapsulate
152      * calls to setUrl, setMethod, and setParams all in one fell swoop.
153      *
154      * @param iurl the URL we wish to access
155      * @param imethod the method we wish to use (either GET or POST)
156      * @param iprops the Map contains our key-value URL parameter pairs.
157      * If the value is a Set, the resulting URL will contain a key-value
158      * mapping for each entry in the Set.
159      * @param iuser the user named required to connect
160      * @param ipwd the password named required to connect
161      * @param ioutputWriter the HttpOutputWriter we wish to write to
162      * @throws MalformedURLException
163      */

164     public void setRequest(URL iurl, String JavaDoc imethod, Map iprops, String JavaDoc iuser, String JavaDoc ipwd, HttpOutputWriter ioutputWriter) throws MalformedURLException {
165         if (iurl!=null) setUrl(iurl);
166         if (imethod!=null) setMethod(imethod);
167         if (iprops!=null) setParams(iprops);
168         if (iuser!=null) setUser(iuser);
169         if (ipwd!=null) setPassword(ipwd);
170         if (ioutputWriter!=null) setOutputWriter(ioutputWriter);
171     }
172
173     /**
174      * Set the URL we wish to access
175      *
176      * @param iurl the URL we wish to access
177      * @throws MalformedURLException
178      */

179     public void setUrl(String JavaDoc iurl) throws MalformedURLException {
180         //if we're setting it back to null, otherwise, create the url
181
//which represents the servlet which will do the generation
182
if (iurl==null) url = null;
183         else setUrl (new URL (iurl));
184     }
185
186     /**
187      * Set the URL we wish to access
188      *
189      * @param iurl the URL we wish to access
190      */

191     public void setUrl(URL iurl) {
192         url = iurl;
193     }
194
195     /**
196      * Get the URL for the HttpRequest object
197      *
198      * @return the URL behind this request
199      */

200     public URL getUrl() {
201         return url;
202     }
203
204     /**
205      * Set the method we wish to use. Valid values are either GET
206      * or POST. Default is GET.
207      *
208      * @param imethod the method we wish to use (either GET or POST)
209      */

210     public void setMethod(String JavaDoc imethod) {
211         if (imethod.toUpperCase().equals(POST)) method = POST;
212         else method = GET;
213     }
214
215     /**
216      * Get the method we're using for this HttpRequest object
217      *
218      * @return the method we're using (either GET or POST)
219      */

220     public String JavaDoc getMethod() {
221         return method;
222     }
223
224     /**
225      * Set the parmeters we wish to pass to the URL as name-value pairs.
226      * If you are using the POST method, it will look for properties in
227      * here. If you are using the get method, you can manually pass the
228      * properties as part of the URL string, and just ignore this method.
229      *
230      * @param iprops the Map contains our key-value URL parameter pairs.
231      * If the value is a Set, the resulting URL will contain a key-value
232      * mapping for each entry in the Set.
233      */

234     public void setParams(Map iprops) {
235         props = iprops;
236     }
237
238     /**
239      * Return the HashMap object for this HttpRequest. If the map is null (ie.
240      * because you are using the GET method), we attempt to look for the
241      * properties in the actual URL string and build a HashMap from that.
242      *
243      * @return a Map containing all the parameters for this HttpRequest
244      */

245     public Map getParams() {
246         //if someone asks for the param map and its null, try
247
//and build it based on the actual URL string
248
if (props==null) {
249             //avoid the obvious errs
250
if (url==null) return null;
251
252             //build the HashMap
253
props = HttpConverter.cvtURLStringToMap (url.toString(), "&");
254         }
255
256         //return the HashMap
257
return props;
258     }
259
260     /**
261      * Set the user (if we need to authenticate in order to make the connection)
262      *
263      * @param iuser the user name
264      */

265     public void setUser(String JavaDoc iuser) {
266         user = iuser;
267         authenticate = (user!=null);
268     }
269
270     /**
271      * Get the user name
272      *
273      * @return the user name
274      */

275     public String JavaDoc getUser() {
276         return user;
277     }
278
279     /**
280      * Set the password (if we need to authenticate in order to make the connection)
281      *
282      * @param ipwd the password
283      */

284     public void setPassword(String JavaDoc ipwd) {
285         password = ipwd;
286         authenticate = (password!=null);
287     }
288
289     /**
290      * Get the password
291      *
292      * @return the password
293      */

294     protected String JavaDoc getPassword() {
295         return password;
296     }
297
298     //saw_121102.2_start
299
/**
300      * Set whether or not to accept cookies from the server.
301      * The default is <code>true</code>.
302      *
303      * Setting this value to <code>false</code> after cookies
304      * have already been obtained does not clear the current
305      * cookies, it simply will not accept any new cookies.
306      *
307      * @see #clearCookies()
308      */

309     public void setAcceptCookies(boolean accept) {
310         this.acceptCookies = accept;
311     }
312
313     /**
314      * Determine whether or not we are accepting cookies.
315      */

316     public boolean getAcceptCookies() {
317         return acceptCookies;
318     }
319
320     /**
321      * Return a list of cookies this client is sending to the server
322      *
323      * @return a list of {@link Cookie cookies}, or <code>null</code> if
324      * the server has not set any cookies in the client
325      *
326      * @see Cookie
327      */

328     public List getCookies() {
329         return cookies;
330     }
331     
332     /**
333      * Clear any cookies this client knows about.
334      */

335     public void clearCookies() {
336         cookies = null;
337     }
338     //saw_121102.2_end
339

340     /**
341      * Set the output writer to be used for posting data
342      *
343      * @param ioutputWriter the HttpOutputWriter
344      */

345     public void setOutputWriter(HttpOutputWriter ioutputWriter) {
346         outputWriter = ioutputWriter;
347     }
348
349     /**
350      * Return the output writer. If none is set, the default will be used.
351      *
352      * @return the HttpOutputWriter
353      */

354     public HttpOutputWriter getOutputWriter() {
355         //if someone asks for the output writer and its null,
356
//return the default
357
if (outputWriter==null) {
358             return new DefaultOutputWriter();
359         } else
360             return outputWriter;
361     }
362
363     //csc_010404_1 - added
364
/**
365      * Return the connection. Only set after connect has been called
366      *
367      * @return the URLConnection
368      */

369     public URLConnection getURLConnection() {
370         return conn;
371     }
372
373     /**
374      * Connect to the URL
375      *
376      * @throws ConnectException
377      * @throws IOException
378      */

379     public void connect() throws ConnectException, IOException {
380         //pre-launch checks
381
if (url==null) throw new ConnectException ("Invalid URL. URL can not be NULL");
382         if (method!=POST && method!=GET) throw new ConnectException ("Invalid Method. Method must be either POST or GET");
383
384 //csc_010404_1 URLConnection conn = null; //saw_121102.2
385

386         //POST
387
if (method==POST) {
388             //open the connection for both output and input
389
//saw_121102.2 URLConnection conn = url.openConnection();
390
conn = url.openConnection(); //saw_121102.2
391
conn.setDoOutput(true);
392
393             //Set up an authorization header with our credentials (this chunk of
394
//code stolen from org.apache.catalina.ant.AbstractCatalinaTask;
395
//thanks to Craig R. McClanahan [craigmcc@apache.org] for pointing
396
//me to this example)
397
if (authenticate) {
398                 String JavaDoc input = user + ":" + password;
399                 String JavaDoc output = new String JavaDoc(Base64.encode(input.getBytes()));
400                 conn.setRequestProperty("Authorization", "Basic " + output);
401             }
402             
403             //write the key values to the stream
404
outStream = conn.getOutputStream();
405             getOutputWriter().writeOutput(outStream);
406
407 //saw_121102.2_start - deferred to down below
408
//now open an input stream to read the response
409
// inStream = conn.getInputStream();
410
// in = new BufferedReader(new InputStreamReader(inStream));
411
//saw_121102.2_end
412
//GET
413
} else {
414             //first see if we have a param structure...if so, build a URL String.
415
if (props!=null) {
416                 //figure out what the current URL is and strip off any parameters
417
String JavaDoc newUrl = getUrl().toString();
418                 int pos = newUrl.indexOf("?");
419                 if (pos>0) newUrl = newUrl.substring(0,pos);
420
421                 //now run through the map and build a new url string
422
setUrl(newUrl+"?"+ HttpConverter.cvtMapToURLString(props, "&"));
423                 newUrl = getUrl().toString();
424                 if (newUrl.endsWith("?")) setUrl(newUrl.substring(0,newUrl.length()-1));
425
426                 //now set the url and set the params object back to null so we don't
427
//need to rebuild the URL string again
428
setParams(null);
429             }
430
431             //open the connection for input
432
//saw_121102.2 URLConnection conn = url.openConnection();
433
conn = url.openConnection(); //saw_121102.2
434
conn.setDoInput(true);
435             
436             //Set up an authorization header with our credentials (this chunk of
437
//code stolen from org.apache.catalina.ant.AbstractCatalinaTask;
438
//thanks to Craig R. McClanahan [craigmcc@apache.org] for pointing
439
//me to this example)
440
if (authenticate) {
441                 String JavaDoc input = user + ":" + password;
442                 String JavaDoc output = new String JavaDoc(Base64.encode(input.getBytes()));
443                 conn.setRequestProperty("Authorization", "Basic " + output);
444             }
445             
446 //saw_121102.2_start - deferred to down below
447
//now get an input stream
448
// inStream = conn.getInputStream();
449
// in = new BufferedReader(new InputStreamReader(inStream));
450
//saw_121102.2_end
451
}
452
453         //saw_121102.2_start
454
//do we have cookies to send?
455
if(cookies != null) {
456             //NOTE: this implementation of cookie support is very basic and
457
//does not completely follow spec. Specifically, cookie expiration
458
//is not checked and a single repeated cookie is not ordered by
459
//the path specifications as the spec requires.
460

461             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
462             int maxVersion = 0;
463             boolean haveCookies = false;
464             Iterator it = cookies.iterator();
465             while (it.hasNext()) {
466                 Cookie cookie = (Cookie)it.next();
467                 if (cookie.getDomain() == null || url.getHost().toLowerCase().endsWith(cookie.getDomain().toLowerCase())) {
468                     if (cookie.getPath() == null || url.getPath().startsWith(cookie.getPath())) {
469                         if (!cookie.getSecure() || url.getProtocol().equalsIgnoreCase("https")) {
470                             // if we're here, then it's safe to transmit the cookie
471
haveCookies = true;
472                             
473                             sb.append(';').append(cookie.getName()).append('=').append(cookie.getValue());
474                             if(cookie.getVersion() > 0) {
475                                 if(cookie.getVersion() > maxVersion) maxVersion = cookie.getVersion();
476                                 if(cookie.getPath() != null) sb.append(";$Path=").append(cookie.getPath());
477                                 if(cookie.getDomain() != null) sb.append(";$Domain=").append(cookie.getDomain());
478                             }
479                         } else {
480                             //System.out.println("Ignoring cookie for secure transmission");
481
}
482                     } else {
483                         //System.out.println("Ignoring cookie for different path: "+cookie.getPath());
484
}
485                 } else {
486                     //System.out.println("Ignoring cookie for different domain: "+cookie.getDomain());
487
}
488             }
489             
490             if (haveCookies) {
491                 String JavaDoc cookieStr;
492                 if(maxVersion == 0) cookieStr = sb.substring(1); // gets rid of first semicolon
493
else cookieStr = "$Version="+maxVersion+sb.toString();
494                 
495                 //System.out.println("Sending header Cookie: "+cookieStr);
496
conn.setRequestProperty("Cookie", cookieStr);
497             }
498         }
499
500         //now open an input stream to read the response
501
inStream = conn.getInputStream();
502         in = new BufferedReader(new InputStreamReader(inStream));
503         
504         //are we accepting cookies, and did the server send any back?
505

506         // dbr_032601.start
507
//List scookies = (List) conn.getHeaderFields().get("Set-Cookie");
508
List scookies = new ArrayList();
509         for(int i = 0; conn.getHeaderFieldKey(i) != null; i++) {
510             if("Set-Cookie".equals(conn.getHeaderFieldKey(i))) {
511                 scookies.add(conn.getHeaderField(i));
512             }
513         }
514         // dbr_032601.end
515
if (acceptCookies && scookies != null) {
516             cookies = new ArrayList(scookies.size());
517             //System.out.println("Got cookie header(s) from server:");
518
Iterator it = scookies.iterator();
519             while (it.hasNext()) {
520                 String JavaDoc cookieStr = (String JavaDoc) it.next();
521                 //System.out.println(" --> " + cookieStr);
522
try {
523                     Cookie cookie = HttpServices.parseCookie(cookieStr);
524                     //System.out.println(" COOKIE: "+HttpServices.formatCookie(cookie));
525
//cookie.setVersion(1); //### FOR TESTING ONLY
526
cookies.add(cookie);
527                 } catch (ParseException e) {
528                     e.printStackTrace();
529                 }
530             }
531         }
532         //saw_121102.2_end
533
}
534
535     /**
536      * Read responses from the URL
537      *
538      * @return a String representation of what we got back
539      * @throws ConnectException
540      * @throws IOException
541      */

542     public String JavaDoc readLine() throws ConnectException, IOException {
543         //pre-launch checks
544
if (in==null) throw new ConnectException ("Connection is not active");
545
546         //get the line
547
String JavaDoc inputLine = in.readLine();
548
549         //if its null, auto disconnect
550
if (inputLine==null) disconnect();
551
552         //now return the String
553
return inputLine;
554     }
555
556     /**
557      * Get the underlying output stream
558      *
559      * @return the output stream
560      * @throws ConnectException
561      */

562     public OutputStream getOutputStream() throws ConnectException {
563         //pre-launch checks
564
if (outStream==null) throw new ConnectException ("Connection is not active");
565
566         //return the input stream
567
return outStream;
568     }
569
570     /**
571      * Get the underlying input stream
572      *
573      * @return the input stream
574      * @throws ConnectException
575      */

576     public InputStream getInputStream() throws ConnectException {
577         //pre-launch checks
578
if (inStream==null) throw new ConnectException ("Connection is not active");
579
580         //return the input stream
581
return inStream;
582     }
583
584     /**
585      * Disconnect from the URL. You really only need to call this
586      * if you terminate the readLine process on your end. if
587      * readLine() encounters a null value, it assumes input is
588      * complete and automatically calls this method.
589      */

590     public void disconnect() {
591         if (outStream!=null) try {outStream.close();} catch (IOException ioe) {}
592         outStream = null;
593         if (in!=null) try {in.close();} catch (IOException ioe) {}
594         in = null;
595         if (inStream!=null) try {inStream.close();} catch (IOException ioe) {}
596         inStream = null;
597     }
598
599     /**
600      * This inner class provides the default mechanism to write to an output stream
601      */

602     class DefaultOutputWriter implements HttpOutputWriter {
603         public void writeOutput(OutputStream outputStream) throws IOException {
604             System.out.println ("Using default HttpOutputWriter to POST data");
605             PrintWriter out = new PrintWriter(outputStream);
606             try {
607                 String JavaDoc paramStr = HttpConverter.cvtMapToURLString(props, "&");
608                 if (paramStr!=null && paramStr.trim().length()>0) out.print (paramStr);
609                 System.out.println ("Data posted!");
610             } finally {
611                 out.close();
612                 outputStream.close();
613             }
614         }
615     }
616
617
618     public static void main(String JavaDoc[] args) {
619         //sample GET
620
try {
621             HttpRequester hr = new HttpRequester();
622 // String urlStr = "http://localhost:8080/manager/list"; //connect to Tomcat manager app
623
// String paramStr = "";
624
String JavaDoc urlStr = "http://localhost:8080/manager/reload?path=/examples"; //connect to Tomcat manager app
625
String JavaDoc paramStr = null;
626             Map props = null;
627             if (paramStr!=null) HttpConverter.cvtURLStringToMap (paramStr, "&");
628             hr.setRequest(urlStr, HttpRequester.GET, props, "admin", "123123", null);
629             hr.connect();
630             String JavaDoc inputLine;
631             while ((inputLine = hr.readLine()) != null) {
632                 System.out.println(inputLine);
633             }
634             hr.disconnect();
635         } catch (Exception JavaDoc e) {
636             e.printStackTrace();
637         }
638 /*
639         //sample POST
640         try {
641             HttpRequester hr = new HttpRequester();
642             String urlStr = "http://localhost:8010/EventHandler6/rocks.examples.ex1.TestEvent.event";
643             String paramStr = "parm1=foo&parm2=blah&parm2=boo";
644             Map props = HttpConverter.cvtURLStringToMap (paramStr, "&");
645             hr.setRequest (urlStr, HttpRequester.POST, props);
646             hr.connect();
647             String inputLine;
648             while ((inputLine = hr.readLine()) != null) {
649                 System.out.println(inputLine);
650             }
651             hr.disconnect();
652         } catch (Exception e) {
653             e.printStackTrace();
654         }
655 */

656
657         //sample cookie support check - saw_121102.2
658
try {
659             HttpRequester hr = new HttpRequester();
660             hr.setRequest("http://www.psycinfo.com/cookie/set-cookie.cfm", HttpRequester.GET, null);
661             hr.connect();
662             String JavaDoc inputLine;
663             while ((inputLine = hr.readLine()) != null) {
664                 System.out.println(inputLine);
665             }
666             hr.disconnect();
667             
668             hr.setRequest("http://www.psycinfo.com/cookie/check-cookie.cfm", HttpRequester.GET, null);
669             hr.connect();
670             while ((inputLine = hr.readLine()) != null) {
671                 System.out.println(inputLine);
672             }
673             hr.disconnect();
674         } catch (Exception JavaDoc e) {
675             e.printStackTrace();
676         }
677
678     }
679 }
680
Popular Tags