Design of an HTTP Server that uses Reflection for Servlets
A Simple Network Application in Java |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
import java.io.*; /** * Constructs servlets appropriate based on * the file-type in the request. * * Note that the Singleton pattern is used to construct * the factory itself. * * @version 0.3 * @author Prof. David Bernstein, James Madison University */ public class HttpServletFactory { // For the Singleton pattern private static HttpServletFactory instance = new HttpServletFactory(); // Actual attributes private File file; private long lastModified; private NameValueMap associations; private static final String FILE_NAME = "associations.dat"; private static final NameValueMap DEFAULT_ASSOCIATIONS = NameValueMap.createNameValueMap(); /** * Default Constructor */ private HttpServletFactory() { file = new File(FILE_NAME); lastModified = -1; associations = NameValueMap.createNameValueMap(); loadAssociations(); } /** * Create an HttpServletFactory */ public static HttpServletFactory createFactory() { return instance; } /** * Construct an HttpServlet * * @param req The HTTP request * @param in The HttpInputStream to read from * @param out The HttpOutputStream to write to */ public HttpServlet createServlet(HttpRequest req, HttpInputStream in, HttpOutputStream out) { Class c; HttpServlet servlet; String className, ext, fname; servlet = null; loadAssociations(); fname = req.getRequestURI(); ext = FileTyper.getExtension(fname); className = associations.getValue(ext); if (className == null) { servlet = new DefaultHttpServlet(in, out); } else if (className.equals("TemplatedHttpServlet")) { servlet = new TemplatedHttpServlet(in, out); } return servlet; } /** * Load the associations between file types and * servlets (if they have changed on disk) */ private void loadAssociations() { BufferedReader in; long modified; modified = file.lastModified(); if (modified > lastModified) { try { in = new BufferedReader(new FileReader(new File(FILE_NAME))); associations.clear(); associations.putPairs(in, "\\s"); lastModified = modified; } catch (Exception e) { associations = DEFAULT_ASSOCIATIONS; } } } }
getConstructors()
:
getConstructor()
:
/** * Construct an HttpServlet * * @param req The HTTP request * @param in The HttpInputStream to read from * @param out The HttpOutputStream to write to */ public HttpServlet createServlet(HttpRequest req, HttpInputStream in, HttpOutputStream out) { Class c; HttpServlet servlet; String className, ext, fname; servlet = null; loadAssociations(); fname = req.getRequestURI(); ext = FileTyper.getExtension(fname); className = associations.getProperty(ext); if (className == null) { servlet = new DefaultHttpServlet(in, out); } else // Use reflection to create an appropriate servlet { try { Class cl = Class.forName(className); Constructor co = cl.getConstructor(new Class[]{HttpInputStream.class, HttpOutputStream.class}); servlet = (HttpServlet)co.newInstance(in, out); } catch (Exception e) { servlet = new DefaultHttpServlet(in, out); } } return servlet; }
newInstance()
newInstance()
requires onesetStreams()
in this case)newInstance()
(cont.)/** * Construct an HttpServlet * * @param req The HTTP request * @param in The HttpInputStream to read from * @param out The HttpOutputStream to write to */ public HttpServlet createServlet(HttpRequest req, HttpInputStream in, HttpOutputStream out) { Class c; HttpServlet servlet; String className, ext, fname; servlet = null; loadAssociations(); fname = req.getRequestURI(); ext = FileTyper.getExtension(fname); className = associations.getProperty(ext); if (className == null) { servlet = new DefaultHttpServlet(in, out); } else // Use reflection to create an appropriate servlet { try { c = Class.forName(className); servlet = (HttpServlet)c.newInstance(); servlet.setStreams(in, out); } catch (Exception e) { servlet = new DefaultHttpServlet(in, out); } } return servlet; }
Class
object's getMethod()
method to get a Method
objectMethod
object's
invoke(Object, Object...)
method (passing it the owning object and the actual
parameters)Class
object's getMethod()
method to get a Method
objectMethod
object's
invoke(null, Object...)
methodimport java.lang.reflect.*; /** * An example of static and non-static method invocation using * reflection. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class MethodExample { /** * The entry point of the application. * * @param args The command-line arguments (which are ignored) */ public static void main(String[] args) throws Exception { Class s_class; Integer i, j; Method s_method; String s, zip; s = new String("James Madison University"); s_class = s.getClass(); // Using a non-static method s_method = s_class.getMethod("indexOf", new Class[]{String.class}); i = (Integer)s_method.invoke(s, "University"); System.out.println(i.intValue()); // Using a static method s_method = s_class.getMethod("valueOf", new Class[]{Object.class}); zip = (String)s_method.invoke(null, new Integer(22801)); System.out.println(zip); } }