- Forward


Design of an HTTP Server that uses Reflection for Servlets
A Simple Network Application in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

A Shortcoming of the Current Implementation
Back SMYC Forward
  • Constructing Servlets:
    • We have hard-coded the construction of servlets
  • A Problem:
    • We have to re-compile whenever we add a servlet
A Shortcoming of the Current Implementation (cont.)
Back SMYC Forward
javaexamples/http/v3/HttpServletFactory.java
 
Improving the Implementation
Back SMYC Forward
  • The General Approach:
    • Use reflection
  • An Observation:
    • Details matter - How should we construct the object?
Constructing Objects Using Reflection
Back SMYC Forward
  • Use a Constructor
    • A Class object's getConstructors() returns a Constructor[]
    • A Class object's getConstructor(Class... parameterTypes) returns a specific Constructor
  • Use a Convenience Method:
    • A Class object's newInstance() method instantiates an object using the default constructor
Using Constructors
Back SMYC Forward
  • Using getConstructors():
    • Requires you to know the order of the constructors
  • Using getConstructor():
    • Requires you to know the parameters in the explicit value constructor
Using Constructors (cont.)
Back SMYC Forward
/** * 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; }
Using newInstance()
Back SMYC Forward
  • The Advantages:
    • Uses the default constructor so is easy
  • The Added Burden:
    • Need to add a default constructor if you don't have one because newInstance() requires one
    • Need to add initializers to perform the tasks completed by the explicit value constructors (e.g., setStreams() in this case)
Using newInstance() (cont.)
Back SMYC Forward
javaexamples/http/v4/HttpServletFactory.java (Fragment: createServlet)
 
What About A Static Factory Method?
Back SMYC Forward
  • Invoking a Non-Static Method Using Reflection:
    • Use a Class object's getMethod() method to get a Method object
    • Call the Method object's invoke(Object, Object...) method (passing it the owning object and the actual parameters)
  • Invoking a Static Method Using Reflection:
    • Use a Class object's getMethod() method to get a Method object
    • Call the Method object's invoke(null, Object...) method
What About a Static Factory Method? (cont.)
Back SMYC Forward
javaexamples/reflection/MethodExample.java
 
What About A Static Factory Method?
Back SMYC Forward
  • An Observation:
    • We need to invoke a static factory method in a particular class
  • The Difficulty:
    • This means that we have to remember to add a static factory method to every servlet that we create
There's Always More to Learn
Back -