KickJava   Java API By Example, From Geeks To Geeks.

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


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.lang.reflect.*;
9 import java.net.*;
10 import java.util.*;
11 import javax.servlet.*;
12 import javax.servlet.http.*;
13 //import javax.servlet.jsp.*;
14

15 /**
16  * A collection of static utility methods useful to servlets.
17  * Some methods require Servlet API 2.2.
18  *
19  * @author <b>Jason Hunter</b>, Copyright &#169; 1998-2000
20  * @version 1.5, 2001/02/11, added getResource() ".." check
21  * @version 1.4, 2000/09/27, finalized getResource() behavior
22  * @version 1.3, 2000/08/15, improved getStackTraceAsString() to take Throwable
23  * @version 1.2, 2000/03/10, added getResource() method
24  * @version 1.1, 2000/02/13, added returnURL() methods
25  * @version 1.0, 1098/09/18
26  */

27 public class ServletUtils {
28
29   /**
30    * Sends the contents of the specified file to the output stream
31    *
32    * @param filename the file to send
33    * @param out the output stream to write the file
34    * @exception FileNotFoundException if the file does not exist
35    * @exception IOException if an I/O error occurs
36    */

37   public static void returnFile(String JavaDoc filename, OutputStream out)
38                              throws FileNotFoundException, IOException {
39     // A FileInputStream is for bytes
40
FileInputStream fis = null;
41     try {
42       fis = new FileInputStream(filename);
43       byte[] buf = new byte[4 * 1024]; // 4K buffer
44
int bytesRead;
45       while ((bytesRead = fis.read(buf)) != -1) {
46         out.write(buf, 0, bytesRead);
47       }
48     }
49     finally {
50       if (fis != null) fis.close();
51     }
52   }
53
54   /**
55    * Sends the contents of the specified URL to the output stream
56    *
57    * @param URL whose contents are to be sent
58    * @param out the output stream to write the contents
59    * @exception IOException if an I/O error occurs
60    */

61   public static void returnURL(URL url, OutputStream out) throws IOException {
62     InputStream in = url.openStream();
63     byte[] buf = new byte[4 * 1024]; // 4K buffer
64
int bytesRead;
65     while ((bytesRead = in.read(buf)) != -1) {
66       out.write(buf, 0, bytesRead);
67     }
68   }
69
70   /**
71    * Sends the contents of the specified URL to the Writer (commonly either a
72    * PrintWriter or JspWriter)
73    *
74    * @param URL whose contents are to be sent
75    * @param out the Writer to write the contents
76    * @exception IOException if an I/O error occurs
77    */

78   public static void returnURL(URL url, Writer out) throws IOException {
79     // Determine the URL's content encoding
80
URLConnection con = url.openConnection();
81     con.connect();
82     String JavaDoc encoding = con.getContentEncoding();
83
84     // Construct a Reader appropriate for that encoding
85
BufferedReader in = null;
86     if (encoding == null) {
87       in = new BufferedReader(
88            new InputStreamReader(url.openStream()));
89     }
90     else {
91       in = new BufferedReader(
92            new InputStreamReader(url.openStream(), encoding));
93     }
94     char[] buf = new char[4 * 1024]; // 4Kchar buffer
95
int charsRead;
96     while ((charsRead = in.read(buf)) != -1) {
97       out.write(buf, 0, charsRead);
98     }
99   }
100
101   /**
102    * Gets an exception's stack trace as a String
103    *
104    * @param e the exception
105    * @return the stack trace of the exception
106    */

107   public static String JavaDoc getStackTraceAsString(Throwable JavaDoc t) {
108     ByteArrayOutputStream bytes = new ByteArrayOutputStream();
109     PrintWriter writer = new PrintWriter(bytes, true);
110     t.printStackTrace(writer);
111     return bytes.toString();
112   }
113
114   /**
115    * Gets a reference to the named servlet, attempting to load it
116    * through an HTTP request if necessary. Returns null if there's a problem.
117    * This method behaves similarly to <tt>ServletContext.getServlet()</tt>
118    * except, while that method may return null if the
119    * named servlet wasn't already loaded, this method tries to load
120    * the servlet using a dummy HTTP request. Only loads HTTP servlets.
121    *
122    * @param name the name of the servlet
123    * @param req the servlet request
124    * @param context the servlet context
125    * @return the named servlet, or null if there was a problem
126    */

127   public static Servlet getServlet(String JavaDoc name,
128                                    ServletRequest req,
129                                    ServletContext context) {
130     try {
131       // Try getting the servlet the old fashioned way
132
Servlet servlet = context.getServlet(name);
133       if (servlet != null) return servlet;
134
135       // If getServlet() returned null, we have to load it ourselves.
136
// Do this by making an HTTP GET request to the servlet.
137
// Use a raw socket connection so we can set a timeout.
138
Socket socket = new Socket(req.getServerName(), req.getServerPort());
139       socket.setSoTimeout(4000); // wait up to 4 secs for a response
140
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
141       out.println("GET /servlet/" + name + " HTTP/1.0"); // the request
142
out.println();
143       try {
144         socket.getInputStream().read(); // Even one byte means its loaded
145
}
146       catch (InterruptedIOException e) { /* timeout: ignore, hope for best */ }
147       out.close();
148
149       // Try getting the servlet again.
150
return context.getServlet(name);
151     }
152     catch (Exception JavaDoc e) {
153       // If there's any problem, return null.
154
return null;
155     }
156   }
157
158   /**
159    * Gets a reference to the given resource within the given context,
160    * making sure not to serve the contents of WEB-INF, META-INF, or to
161    * display .jsp file source.
162    * Throws an IOException if the resource can't be read.
163    *
164    * @param context the context containing the resource
165    * @param resource the resource to be read
166    * @return a URL reference to the resource
167    * @exception IOException if there's any problem accessing the resource
168    */

169   public static URL getResource(ServletContext context, String JavaDoc resource)
170                                        throws IOException {
171     // Short-circuit if resource is null
172
if (resource == null) {
173       throw new FileNotFoundException(
174         "Requested resource was null (passed in null)");
175     }
176
177     if (resource.endsWith("/") ||
178         resource.endsWith("\\") ||
179         resource.endsWith(".")) {
180       throw new MalformedURLException("Path may not end with a slash or dot");
181     }
182
183     if (resource.indexOf("..") != -1) {
184       throw new MalformedURLException("Path may not contain double dots");
185     }
186
187     String JavaDoc upperResource = resource.toUpperCase();
188     if (upperResource.startsWith("/WEB-INF") ||
189         upperResource.startsWith("/META-INF")) {
190       throw new MalformedURLException(
191         "Path may not begin with /WEB-INF or /META-INF");
192     }
193
194     if (upperResource.endsWith(".JSP")) {
195       throw new MalformedURLException(
196         "Path may not end with .jsp");
197     }
198
199     // Convert the resource to a URL
200
URL url = context.getResource(resource);
201     if (url == null) {
202       throw new FileNotFoundException(
203         "Requested resource was null (" + resource + ")");
204     }
205
206     return url;
207   }
208 }
209
Popular Tags