This section shows how to
- call another Servlet (or any other kind of active resource) to process a request
A Servlet can make a request to an active resource on the web server just like a client can (by requesting a URL). The Servlet API supports a more direct way of accessing server resources from within a Servlet which is running in the server than opening a socket connection back to the server. A Servlet can either hand off a request to a different resource or include the response which is created by that resource in its own response. It is also possible to supply user-defined data when calling an active resource which provides for an elegant way of doing inter-Servlet communication.
Example.
We're building an online shop with an ItemServlet
which takes an argument item=number
and returns a paragraph of HTML text with a description of the item which is retrieved from a database.
A second Servlet, the PresentationServlet
, takes the same argument and creates a complete HTML page which includes the output of the ItemServlet
. If the item
argument is missing, the request is delegated to an ErrorServlet
which returns a formatted error message.
public class PresentationServlet extends HttpServlet
{
private static class ItemNotFoundException extends Exception
{
ItemNotFoundException() { super("Item not found"); }
}
protected void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
String item = req.getParameter("item");
if(item == null)
{
req.setAttibute("exception", new ItemNotFoundException());
getServletContext()
.getRequestDispatcher("/servlet/ErrorServlet")
.forward(req, res);
}
else
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.print("<HTML><HEAD><TITLE>Item " + item + "</TITLE>"+
"</HEAD><BODY>Item " + item + ":<P>");
getServletContext()
.getRequestDispatcher("/servlet/ItemServlet?item="+item)
.include(req, res);
out.print("</BODY></HTML>");
}
}
}
In the doGet
method we first check for the existence of the item
argument. If it is present (second branch of the if
statement) the Servlet is responding with an HTML document in the usual way. In the middle of the document the response body of the ItemServlet
is included by asking the ItemServlet
's RequestDispatcher
(whis is obtained through the ServletContext
) to perform that operation.
If no item
attribute was specified, the request is delegated to the ErrorServlet
in a similar way. Note that this time we are using the RequestDispatcher
's forward
method (instead of include
). This method can be called only once and only if neither getOutputStream
nor getWriter
has been called, but it allows the included Servlet to set headers and the response code (which is required to create a proper HTTP error response message).
The ItemServlet
gets its item
argument from the query string. That way it can also be accessed directly via an HTTP request, but argument values have to be represented as url-encoded strings (which is no problem in this case). The ErrorServlet
takes an exception
argument of type java.lang.Exception
which is provided as a request attribute. The ErrorServlet
uses the ServletRequest
method getAttribute
to read the attribute.
Note that a server which supports load balancing could run the Servlets on different JVMs. All custom request attributes should be serializable to allow them to be moved from one JVM to another.
3.3 Accessing Passive Server Resources [API 2.1]
This section shows how to
- access a resource in the server's document tree
Passive server resources (e.g. static HTML pages which are stored in local files) are not accessed with RequestDispatcher
objects. The ServletContext
method getResource(String path)
returns a URL
object for a resource specified by a local URI (e.g. "/
" for the server's document root) which can be used to examine the resource.
If you only want to read the resource's body you can directly ask the ServletContext
for an InputStream
with the getResourceAsStream(String path)
method.
ServletContext
method getRealPath(String path)
to find a path in the local file system to a resource. This method is less general than the one described above because it doesn't allow you to access resources which are not stored in local files. Accessing Servlet Resources
This section shows how to
- access resources which belong to a Servlet
A Servlet may need to access additional resources like configuration files whose locations should not need to be specified in init parameters. Those resources can be accessed with the methods getResource(String name)
and getResourceAsStream(String name)
of the java.lang.Class
object which represents the Servlet's class.
Example. The following code gets an InputStream
for a configuration file named myservlet.cfg
which resides in the same directory as the class in which the code is executed:
InputStream confIn =
getClass().getResourceAsStream("myservlet.cfg");
Note that the Servlet engine's Servlet class loader must implement the getResource
and getResourceAsStream
methods in order for this to work. This may not be the case with all Servlet engines.
Sharing Data Between Servlets [API 2.1]
This section shows how to
- share data between Servlets
Version 2.1 of the Servlet API offers a new way of sharing named objects between all the Servlets in a Servlet context (and also other contexts, as you'll see below) by binding the objects to the ServletContext
object which is shared by several Servlets.
The ServletContext
class has several methods for accessing the shared objects:
-
public void setAttribute(String name, Object object)
adds a new object or replaces an old object by the specified name. The attribute name should follow the same naming convention as a package name (e.g. a Servletcom.foo.fooservlet.FooServlet
could have an attributecom.foo.fooservlet.bar
).Just like a custom
ServletRequest
attribute, an object which is stored as aServletContext
attribute should also be serializable to allow attributes to be shared by Servlets which are running in different JVMs on different machines in a load-balancing server environment. -
public Object getAttribute(String name)
returns the named object ornull
if the attribute does not exist.In addition to the user-defined attributes there may also be predefined attributes which are specific to the Servlet engine and provide additional information about a Servlet(Context)'s environment.
-
public Enumeration getAttributeNames()
returns anEnumeration
of the names of all available attributes. -
public void removeAttribute(String name)
removes the attribute with the specified name if it exists.
The separation of Servlets into Servlet contexts depends on the Servlet engine. The ServletContext
object of a Servlet with a known local URI can be retrieved with the method public ServletContext getContext(String uripath)
of the Servlet's own ServletContext
. This method returns null
if there is no Servlet for the specified path or if this Servlet is not allowed to get the ServletContext
for the specified path due to security restrictions.
0 comments:
Post a Comment