Vous êtes sur la page 1sur 12

Interservlet Communication

Servlets running together in the same server have several ways to


communicate with each other. There are three major reasons to
useinterservlet communication:
Direct servlet manipulation
A servlet can gain access to the other currently loaded servlets and
perform some task on each. The servlet could, for example,
periodically ask every servlet to write its state to disk to protect
against server crashes.
Servlet reuse
One servlet can use another's abilities to perform a task. Think back
to the ChatServlet from the previous chapter. It was written as a
server for chat applets, but it could be reused (unchanged) by
another servlet that needed to support an HTML-based chat
interface.
Servlet collaboration
The most common, situation involves two or more servlets sharing
state information. For example, a set of servlets managing an online
store could share the store's product inventory count. Session
tracking is a special case of servlet collaboration.

Servlet Manipulation
Direct servlet manipulation involves one servlet accessing the loaded
servlets on its server and optionally performing some task on one or
more of them. A servlet obtains information about other servlets
through the ServletContext object. Use getServlet() to get a particular
servlet:
public Servlet ServletContext.getServlet(String name) throws
ServletException
This method returns the servlet of the given name, or null if the
servlet is not found.
Viewing the Currently Loaded Servlets
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Loaded extends HttpServlet {


public void doGet(HttpServletRequest req, HttpServletResponse
res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();

ServletContext context = getServletContext();


Enumeration names = context.getServletNames();
while (names.hasMoreElements()) {
String name = (String)names.nextElement();
Servlet servlet = context.getServlet(name);
out.println("Servlet name: " + name);
out.println("Servlet class: " + servlet.getClass().getName());
out.println("Servlet info: " + servlet.getServletInfo());
out.println();
}
}
}

Servlet Reuse
The major challenge with servlet reuse is for the "user" servlet to
obtain the proper instance of "usee" servlet when the usee servlet
has not yet been loaded into the server.
Directly creating a new instance of the usee servlet doesn't work
either, as the newly created servlet doesn't have access to its own
ServletConfig and ServletContext objects. Servlet API distinctly
lacks any methods whereby a servlet can control the servlet life cycle,
for itself or for other servlets. This is considered a security risk and is
officially "left for future consideration."

Servlet Collaboration
Sometimes servlets have to cooperate, usually by sharing some
information. We call communication of this sort servlet collaboration.
Collaborating servlets can pass the shared information directly from
one servlet to another through method invocations, as shown earlier.
This approach requires each servlet to know the other servlets with
which it is collaborating--an unnecessary burden. There are several
better techniques.
Filters in servlet

The Java Servlet 2.3 specification introduced the concept of filters,


components that canintercept and modify requests to and responses
from servlets and JSPs (JavaServer Pages). You can extend and
enhance an application by adding one or more filters, and you can
apply filters individually or in a series called a filter chain.

From a developer's point of view, a filter is a Java class that


implements the interface defined in javax.servlet.Filter. The key
method is doFilter, which has the following signature:

public void doFilter(ServletRequest request, ServletResponse


response, FilterChain chain)

<filter>
<filter-name>FilterMyDocs</filter-name>
<filter-class>mypackage1.FilterTwo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterMyDocs</filter-name>
<url-pattern>/mydocs/*</url-pattern>
</filter-mapping>

Filters can perform many different types of functions. We'll discuss


examples of the italicized items in this paper:

Authentication-Blocking requests based on user identity.


Logging and auditing-Tracking users of a web application.
Image conversion-Scaling maps, and so on.
Data compression-Making downloads smaller.
Localization-Targeting the request and response to a particular
locale.
XSL/T transformations of XML content-Targeting web application
responses to more that one type of client.
Programming Filters
The filter API is defined by the Filter, FilterChain,
and FilterConfig interfaces in thejavax.servlet package. You define a
filter by implementing the Filter interface. A filter chain, passed to a
filter by the container, provides a mechanism for invoking a series of
filters. A filter config contains initialization data.
The most important method in the Filter interface is
the doFilter method, which is the heart of the filter. This method
usually performs some of the following actions:

Examines the request headers


Customizes the request object if it wishes to modify request headers
or data or block the request entirely
Customizes the response object if it wishes to modify response
headers or data
Invokes the next entity in the filter chain. If the current filter is the last
filter in the chain that ends with the target servlet, the next entity is
the resource at the end of the chain; otherwise, it is the next filter that
was configured in the WAR. It invokes the next entity by calling
the doFilter method on the chain object (passing in the request and
response it was called with, or the wrapped versions it may have
created). Alternatively, it can choose to block the request by not
making the call to invoke the next entity. In the latter case, the filter is
responsible for filling out the response.
Examines response headers after it has invoked the next filter in the
chain
Throws an exception to indicate an error in processing
In addition to doFilter, you must implement
the init and destroy methods. The in it method is called by the
container when the filter is instantiated. If you wish to pass
initialization parameters to the filter you retrieve them from
the FilterConfig object passed to init.

public final class HitCounterFilter implements Filter {


private FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig)
throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (filterConfig == null)
return;
StringWriter sw = new StringWriter();
PrintWriter writer = new PrintWriter(sw);
Counter counter = (Counter)filterConfig.
getServletContext().
getAttribute("hitCounter");
writer.println();
writer.println("===============");
writer.println("The number of hits is: " +
counter.incCounter());
writer.println("===============");

// Log the resulting string


writer.flush();
filterConfig.getServletContext().
log(sw.getBuffer().toString());
...
chain.doFilter(request, wrapper);
...
}
}

The hit counter filter described in Programming Filters inserts the


value of the counter into the response. The elided code
from HitCounterFilter is:

PrintWriter out = response.getWriter();


CharResponseWrapper wrapper = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrapper);
if(wrapper.getContentType().equals("text/html")) {
CharArrayWriter caw = new CharArrayWriter();
caw.write(wrapper.toString().substring(0,
wrapper.toString().indexOf("</body>")-1));
caw.write("<p>\nYou are visitor number
<font color='red'>" + counter.getCounter() + "</font>");
caw.write("\n</body></html>");
response.setContentLength(caw.toString().length());
out.write(caw.toString());
} else
out.write(wrapper.toString());
out.close();

SingleThreadModel in Servlet
Servlet in java application can be accessed by multiple users at a
same time
SingleThreadModel in servlet, we can use it to restrict access of more
than one user at a same time. SingleThreadModel is useful in case
you required to process one request at one time, no other can access
that process when servlet is in use.
To make servlet a Single thread, need to implement
SingleThreadModel interface. This is an empty, tag interface that
defines no methods or variables and serves only to flag the servlet as
wanting the alternate life cycle.
The example is given of SingleThreadModel in Servlet.
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;

public class TestServlet extends HttpServlet implements


SingleThreadModel {

A server that loads a SingleThreadModel servlet must guarantee,


according to the Servlet API documentation, "that no two threads will
execute concurrently the service method of that servlet."

Thus, any servlet implementing SingleThreadModel can be


considered thread safe and isn't required to synchronize access to its
instance variables.
A single thread model for servlets is generally used to protect
sensitive data ( bank account operations ).
Singlethread means only one thread, can access the service method
of the servlet, to reduce the overhead the servlet container creates
pool of servlet instances to handle n number of request that is
depend on the servler configuration.

Servlet Chaining

Servlet Chaining means the output of one servlet act as a input to


another servlet. Servlet Aliasing allows us to invoke more than one
servlet in sequence when the URL is opened with a common servlet
alias. The output from first Servlet is sent as input to other Servlet
and so on. The Output from the last Servlet is sent back to the
browser. The entire process is called Servlet Chaining.

// FirstServlet

import javax.servlet.*;
import java.io.*;
import javax.servlet.http.*;

public class FirstServlet extends HttpServlet {


String name ;
ServletConfig config;

public void doGet(HttpServletRequest request ,


HttpServletResponse response)
throws ServletException , IOException {

response.setContentType("text/plain");

PrintWriter out = response.getWriter();


name = request.getParameter("name");
RequestDispatcher rd = config.
getServletContext().getRequestDispatcher("SecondServlet");

if(name!=null) {
request.setAttribute("UserName",name);
rd.forward(request , response);
// Forward the value to another Secondservlet
} else {
response.sendError(response.SC_BAD_REQUEST,
"UserName Required");
}
}
}

// SecondServlet

import javax.servlet.*;
import java.io.*;
import javax.servlet.http.*;
public class SecondServlet extends HttpServlet {
public void doGet(HttpServletRequest request ,
HttpServletResponse response)
throws ServletException , IOException {

response.setContentType("text/plain");
PrintWriter out = response.getWriter();
String UserName = (String)request.getAttribute("UserName");

// Extracting the value which is set in FirstServlet


out.println("The UserName is "+ UserName);
}
}

servlet attribute scopes


Request Attributes.
Attributes are objects associated with a request. Attributes may be
set by the container to express information that otherwise could not
be expressed via the API, or may be set by a servlet to communicate
information to another servlet (via the RequestDispatcher). Attributes
are accessed with the following methods of
the ServletRequest interface:
getAttribute
Returns the value of the named attribute as an Object, or null if no
attribute of the given name exists. Attributes can be set two ways.
The servlet container may set attributes to make available custom
information about a request. Attributes can also be set
programatically using setAttribute(String, Object). This allows
information to be embedded into a request before
aRequestDispatcher call. Attribute names should follow the same
conventions as package names. This specification reserves names
matching java.*, javax.*, and sun.*.
getAttributeNames
Returns an Enumeration containing the names of the attributes
available to this request. This method returns an
EMPTY Enumerationif the request has no attributes available to it.
setAttribute
Stores an attribute in this request. Attributes are reset between
requests. This method is most often used in conjunction
withRequestDispatcher. Attribute names should follow the same
conventions as package names. Names beginning
with java.*, javax.*, and com.sun.*, are reserved for use by Sun
Microsystems. If the object passed in is null, the effect is the same as
callingremoveAttribute(String).
removeAttribute
Removes an attribute from this request. This method is not generally
needed as attributes only persist as long as the request is being
handled.
Session Attributes.
A servlet can bind an object attribute into
an HttpSession implementation by name. Any object bound into a
session is available to any other servlet that belongs to the
same ServletContext and handles a request identified as being a part
of the same session.
getAttribute
Returns the object bound with the specified name in this session,
or null if no object is bound under the name.
getAttributeNames
Returns an Enumeration of String objects containing the names of all
the objects bound to this session.
setAttribute
Binds an object to this session, using the name specified. If an object
of the same name is already bound to the session, the object is
replaced. After this method executes, and if the new object
implements HttpSessionBindingListener, the container
callsHttpSessionBindingListener.valueBound. The container then
notifies any HttpSessionAttributeListeners in the web application. If
an object was already bound to this session of this name that
implements HttpSessionBindingListener,
itsHttpSessionBindingListener.valueUnbound method is called. If the
value passed in is null, this has the same effect as
callingremoveAttribute().
removeAttribute
Removes the object bound with the specified name from this session.
If the session does not have an object bound with the specified name,
this method does nothing. After this method executes, and if the
object implements HttpSessionBindingListener, the container
calls HttpSessionBindingListener.valueUnbound. The container then
notifies any HttpSessionAttributeListeners in the web application.
Some objects may require notification when they are placed into, or
removed from, a session. This information can be obtained by having
the object implement the HttpSessionBindingListener interface. This
interface defines the following methods that will signal an object being
bound into, or being unbound from, a session
valueBound
valueUnbound
The valueBound method must be called BEFORE the object is made
available via the getAttribute method of the HttpSession interface.
The valueUnbound method must be called AFTER the object is no
longer available via the getAttribute method of
the HttpSessioninterface.
Multiple servlets executing request threads may have active access
to a single session object at the same time. The Developer has the
responsibility for synchronizing access to session resources as
appropriate.
Within an application marked as distributable, all requests that are
part of a session must be handled by one Java Virtual Machine (JVM)
at a time. The container must be able to handle all objects placed into
instances of the HttpSession class using
the setAttribute or putValuemethods appropriately. The following
restrictions are imposed to meet these conditions:
The container must accept objects that implement
the Serializable interface.
The container may choose to support storage of other designated
objects in the HttpSession, such as references to Enterprise
JavaBeans components and transactions.
Migration of sessions will be handled by container-specific facilities.
The distributed servlet container must throw
an IllegalArgumentException for objects where the container cannot
support the mechanism necessary for migration of the session storing
them.
Containers must notify any session attributes implementing
the HttpSessionActivationListener during migration of a session. They
must notify listeners of passivation prior to serialization of a session,
and of activation after deserialization of a session.
Application Developers writing distributed applications should be
aware that since the container may run in more than one Java virtual
machine, the developer cannot depend on static variables for storing
an application state. They should store such states using an
enterprise bean or a database.

Context Attributes.
A servlet can bind an object attribute into the context by name. Any
attribute bound into a context is available to any other servlet that is
part of the same Web application. The following methods
of ServletContext interface allow access to this functionality:
setAttribute
Binds an object to a given attribute name in this servlet context. If the
name specified is already used for an attribute, this method will
REPLACE the attribute with the new to the new attribute. If listeners
are configured on the ServletContext the container notifies them
accordingly. If a null value is passed, the effect is the same as
calling removeAttribute(). Attribute names should follow the same
convention as package names. The Java Servlet API specification
reserves names matching java.*, javax.*, and sun.*.
getAttribute
Returns the servlet container attribute with the given name, or null if
there is no attribute by that name. An attribute allows a servlet
container to give the servlet additional information not already
provided by this interface. See your server documentation for
information about its attributes. A list of supported attributes can be
retrieved using getAttributeNames. The attribute is returned as
ajava.lang.Object or some subclass. Attribute names should follow
the same convention as package names. The Java Servlet API
specification reserves names matching java.*, javax.*, and sun.*.
getAttributeNames
Returns an Enumeration containing the attribute names available
within this servlet context. Use the getAttribute(String) method with an
attribute name to get the value of an attribute.
removeAttribute
Removes the attribute with the given name from the servlet context.
After removal, subsequent calls to getAttribute(String) to retrieve the
attribute’s value will return null. If listeners are configured on
the ServletContext the container notifies them accordingly.