Web Server Java -- Servlets and JSP
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
JSP Include/Forward
Problem:
You want to write a "page-composite" JSP that includes other
pages or passes control to another page.
Solution:
Use <jsp:include> or <jsp:forward>.
Discussion
Suppose you have some common HTML code that you want to appear on every page, such as a navigator or header. You could copy it into each HTML and JSP file, but if it changed, you'd have to find all the files that used it and update each of them. It would be much easier to have one copy and include it everywhere you need it. Most webs servers feature such a mechanism already (e.g., server-side includes). However, using JSP's mechanism has some advantages, such as the ability to attach objects to a request, a topic I'll explore in JavaServer Pages Using a Servlet.
The basic mechanism is simply to have <jsp:include> with a PAGE attribute naming the page to be included, and end with </jsp:include>.
For convenience, you can put the / at the end of the opening tag and omit the
closing tag. Much of this syntax is taken from XML namespaces (see Chapter
21). The FLUSH attribute is also required, and it must have the value TRUE;
this is to remind you that, once you do an include, the contents of the output
are actually written. Therefore, you can no longer do anything that involves
sending HTTP headers, such as changing content type or transferring control
using an HTTP redirect request. So a full JSP include might look like
this:
<H2>News of the day</H2>
<jsp:include page="./news.jsp" flush="true" />
The jsp:forward request is similar to
a jsp:include, but you don't get control back
afterwards. The attribute flush="true" is required
on some JSP engines (including the release of Tomcat at the time this book
went to press) to remind you that once you do this include, you have committed
your output (prior to the include, the output might be all in a buffer).
Therefore, as I just stated, you can no longer do anything that might generate
headers, including setContentType(), sendRedirect( ), and so on.
An alternate include mechanism is <%@include file="filename"%>. This mechanism is a bit more
efficient (the inclusion is done at the time the JSP is being compiled), but
is limited to including text files (the file is read, rather than being
processed as an HTTP URL; so if you include, say, a CGI script, the contents
of your CGI script are revealed in the JSP output: not useful!). The
<jsp:include> can include a URL of any type (HTML,
servlet, JSP, CGI, even PHP or ASP).
JavaServer Pages Using a Servlet
Problem:
It may seem that servlets and JSPs are mutually exclusive, but
in fact they work well together. You can reduce the amount of Java coding in
your JSP by passing control from a servlet to a JSP.
Solution:
Use the Model-View-Controller paradigm, and implement it using
ServletDispatcher().forward( ).
Discussion
Model-View-Controller is a paradigm for building programs that
interact well with the user. The Model is an object
or collection that represents your data; the View is
what the user sees; and the Controller responds to
user request. Think of a slide-show (presentation) program: you probably have
a text view, a slide view, and a sorter view. Yet when you change the data in
any view, all the other views are updated immediately. This is because MVC
allows a single model to have multiple views attached to it. MVC provides the
basis for most well-designed GUI applications.
Using the Model-View-Controller paradigm, a servlet can be the
controller and the JSP can be the view. A servlet, for example, could receive
the initial request from the form, interrogate a database based upon the
query, construct a collection of objects matching the user's query, and
forward it to a JSP to be displayed (the servlet can attach data it found to
the request). A good example of this is a search page, which might have only a
few (or even one) form parameters, so using a JSP with a bean to receive the
results would be overkill. A better design is to have a servlet retrieve the
form parameter and contact the search API or database. From there, it would
retrieve a list of pages matching the query. It could package these into a
Vector or ArrayList, attach this to the request, and forward it to a JSP for formatting.
The basic syntax of this is:
ArrayList searchResultsList = // get from the query
RequestDispatcher disp;
disp = getServletContext( ).getRequestDispatcher("searchresults.jsp");
request.setAttribute("my.search.results", searchResultsList);
disp.forward(request, response);
This causes the servlet to pass the search results to the JSP. The JSP can retrieve the result set using this code:
ArrayList myList = (ArrayList) request.getAttribute("my.search.results");
You can then use a for loop to print the contents of the search request. Note that the URL in the getRequestDispatcher( ) call must be a call to the same
web server, not to a server on a different port or machine.