Using the Tomcat servlet engine
Install the Tomcat servlet engine, obtained from jakarta.apache.org. It is
the reference implementation for the Java servlet specification. Tomcat 4.0
implements the 2.3 specification. It may be used for all the examples in
Chapter 18.
Installing Tomcat
Download Tomcat from
http://jakarta.apache.org/builds/jakarta-tomcat-4.0/nightly/
Set an envirnonment variable, CATALINA_HOME, to the path of the directory in
which Tomcat is installed. Start Tomcat using the command
%CATALINA_HOME%\bin\startup
Stop Tomcat using the command
%CATALINA_HOME%\bin\shutdown
To test, enter http://localhost:8080/ in the browser. The Tomcat homepage
should appear.
Changes to Sections 18.1, 18.2, 18.4, and 18.5
Put the servlet class files in
%catalina_home%\webapps\examples\WEB-INF\classes
Try
http://localhost:8080/
to see the examples bundled with Tomcat. To run the servlets of the text use
the URL
http://localhost:8080/examples/servlet/Welcome
where Welcome is the name of the servlet in Example 18.1. Figure 18.1 is
the result.
To use the Tomcat web server put HTML files in
%catalina_home%\webapps\ROOT\
and browse with the URL
http://localhost:8080/webpagename.html
Change the action in Figure 18.3 to
http://localhost:8080/examples/servlet/GetOrder
Make similar changes to the other URLs in Section 18.2
Changes to Section 18.6
Put GetJspOrder.html and GetOrder.jsp in
%catalina_home%\webapps\examples\jsp
Use the URL
http://localhost:8080/examples/jsp/GetJspOrder.html
Do the same with PostOrder.jsp and PostJspOrder.html.
Use the URL
http://localhost:8080/examples/jsp/PostJspOrder.html
Do the same for PostOrderBean.jsp and PostJspOrderBean.html, and put
OrderBean.class in
%catalina_home%\webapps\examples\WEB-INF\classes\order
Use the URL
http://localhost:8080/examples/jsp/PostJspOrderBean.html
Changes to Section 18.3
The Java Servlet 2.3 specification provides servlet filtering which replaces
the servlet chaining of Section 18.3. JavaServer Pages (Section 18.6) may
be used instead of server-side includes.
ServletFilters
A servlet filter can intercept a request, processing it before it reaches
the servlet. It can also process the servlet's response. We show an example
of each.
The Filter interface has three methods.
void init(FilterConfig config)
Called when the filter is placed in service.
void destroy()
Called when the filter is removed from service.
void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain)
Performs the filtering.
Filters use a FilterChain to invoke the next filter in the chain. The
FilterChain interface provides the method
void doFilter(ServletRequest req, ServletResponse resp)
The FilterConfig interface represents an object that can be used to pass
information to a filter during initialization.
Filtering a Request
In RequestFilter.java, we check if the request provides an Accept header.
If it does not, we refuse the request, otherwise we pass it on to the servlet.
package request;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class RequestFilter implements Filter {
private FilterConfig fc = null;
public void init(FilterConfig f) {
fc = f;
}
public void destroy() {
fc = null;
}
public void doFilter(ServletRequest req,
ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
if (((HttpServletRequest)req).getHeader("Accept") == null) {
PrintWriter pw = resp.getWriter();
pw.println("Can't help you today");
return;
}
chain.doFilter(req, resp);
}
}
Deploying a Filter
Create a directory named "request" in
%catalina-home%\webapps\examples\WEB-INF\classes
Compile RequestFilter.java using
javac -classpath %catalina_home%\common\lib\servlet.jar
request\RequestFilter.java
Edit the configuration file web.xml in the examples\WEB-INF directory to
include
RequestFilter
request.RequestFilter
in the section with the other tags. Include
RequestFilter
/*
in the section with the other tags. The URL pattern "/*"
means that the filter will apply to all requested URLs.
Restart Tomcat after changing web.xml.
Using RequestFilter
To test RequestFilter we first deploy the Welcome servlet of Example
18.1 by copying Welcome.class to
%catalina-home%\webapps\examples\WEB-INF\classes
Entering
http://localhost:8080/examples/servlet/Welcome
in a browser will produce the message of Figure 18.1.
However using the VerySimpleBrowser of Example 16.8
java VerySimpleBrowser localhost 8080
/examples/servlet/Welcome
produces
Connected to host localhost/127.0.0.1
Can't help you today
because VerySimpleBrowser does not send an Accept header.
Filtering a Response
We redo the servlet chaining example using a servlet filter. The
LuckyWelcome servlet of Example 18.6 uses a non-standard
tag. Using servlet chaining, the LuckyTag servlet of Example 18.7
processes the repsonse of Example 18.6 to interpret the tag. Here
we use a servlet filter for that purpose.
Because we are not using a MIME filter, we change Example 18.6 to set
the content type to text/html instead of custom/lucky. We place it in a package
named lucky, creating a directory by that name in examples\WEB-INF\classes.
The filter simply wraps the servlet response and passes it to the next
filter, if any, in the chain.
package lucky;
import java.io.*;
import javax.servlet.*;
public class LuckyFilter implements Filter {
private FilterConfig fc = null;
public void init(FilterConfig f) {
fc = f;
}
public void destroy() {
fc = null;
}
public void doFilter(ServletRequest req,
ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
LuckyWrapper luckyWrap = new LuckyWrapper(resp);
chain.doFilter(req, luckyWrap);
}
}
The LuckyWrapper class extends HttpServletResponseWrapper to be able to
transform the response. It overrides the getWriter method to return a
LuckyWriter rather than the default Writer associated with the response.
package lucky;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LuckyWrapper extends HttpServletResponseWrapper {
private PrintWriter luckyWriter;
public LuckyWrapper(ServletResponse resp) {
super((HttpServletResponse)resp);
try {
luckyWriter = new LuckyWriter(resp.getWriter());
}catch(IOException e) {
e.printStackTrace();
}
}
public PrintWriter getWriter() throws IOException {
return luckyWriter;
}
}
The LuckyWriter class overides the println method to intercept the tag
and replace it by six lucky numbers, which will be sent to the client.
package lucky;
import java.io.*;
public class LuckyWriter extends PrintWriter {
public LuckyWriter(OutputStream o) {
super(o);
}
public LuckyWriter(PrintWriter p) {
super(p);
}
public void println(String line) {
int index = line.toUpperCase().indexOf("");
if(index == -1)
super.println(line);
else {
super.println("Your lucky numbers are:
");
for(int i=0; i<6; i++)
super.println((int)(51*Math.random()+1)+ " ");
super.println("
");
}
}
}
Deploying LuckyFilter
Create a directory named "lucky" in
%catalina-home%\webapps\examples\WEB-INF\classes
Compile LuckyFilter.java, LuckyWrapper.jav, LuckyWriter.java, and
LuckyWelcome.java using
javac -classpath %catalina_home%\common\lib\servlet.jar lucky\Lucky*.java
Edit the configuration file web.xml in the examples\WEB-INF directory to
include
LuckyFilter
lucky.LuckyFilter
in the section with the other tags. Include
LuckyFilter
/lucky/*
in the section with the other tags. The URL pattern
"/lucky/*" means that the filter will apply to all requested URLs which
include "lucky" before the servlet requested. In this way we can isolate the
servlets that use the tag and not waste time using the filter on other
servlets. Restart Tomcat after changing web.xml.
We want to use the LuckyWelcome servlet with the /lucky prefix so the
request will trigger the filter. To do that we modify web.xml to include
LuckyWelcome
lucky.LuckyWelcome
in the section and
LuckyWelcome
/lucky/welcome
in the section.
Entering
http://localhost:8080/examples/lucky/welcome
in the browser will produce output like that shown in Figure 18.14.