One of the benefits of using Java servlets and JSP technology is the ability to delegate tasks among different parts. Requests are often forwarded or redirected by serlvets or JSPs such that a client request for a particular server resource may be actually served by another resource. To take full advantage of these mechanisms, it is important to understand the differences between redirecting and forwarding:
response.sendRedirect(some-url)
, the server sends an HTTP 302 message back
to the client, instructing the client to access a new resource at the specified URL. The initial request object that
was accessed by the original JSP or servlet terminates when that page completes its execution (that is, at the end
of the service()
method), so the new resource loses the initial request state.<jsp:forward>
or rd.forward(request, response)
,
the second resource maintains object bindings to the request and its state. This allows the initial JSP or servlet to
do some work, such as the business logic of the page, and then send information to the presentation JSP. Note that
the forwarding mechanism does not require a trip across the network and back to the client.The Java-based Web architectures that use a "Model 2" approach, such as dispatcher, n-tiered, and mediator-view architectures, all rely on the ability of a servlet to delegate, or "dispatch," a request to another resource. Request delegation is handled by RequestDispatcher objects, which can dispatch a request to static resources such as HTML pages or dynamic servlets and JSPs. This dispatching occurs by either "including" a page or "forwarding" to another page. The dispatched resource can access the current state of the request, the session, or the application.
In servlets, you can call the servlet context's getRequestDispatcher()
method to obtain a RequestDispatcher.
In a typical servlet, the following code can be used to call another servlet:
RequestDispatcher rd = getServletContext().getRequestDispatcher("s");
where s is another servlet.
The request dispatcher's include()
method enables another resource to be included in the response to
a client request. Included resources cannot modify the HTTP response headers; whatever is set by the calling resource
will hold true. For example, to include the file footer.html in a servlet:
RequestDispatcher rd = getServletContext().getRequestDispatcher("/footer.html"); rd.include(request, response);
If the included resource is a servlet or JSP, any objects that are bound to the request can be accessed by the included resource.
The forward()
method forwards the client request to another resource, such as a servlet or JSP. The
original resource can perform some preliminary work, such as establishing connections to a SAS server or performing
some calculations, before sending the request to a resource that will provide the response. As with the include()
method, any objects that are bound to the request can be accessed by the forwarded resource. For example, to
forward the request to the template.jsp file and bind the user object to the request:
RequestDispatcher rd = getServletContext().getRequestDispatcher("/template.htm"); request.setAttribute("user", user); rd.forward(request, response);
The <jsp:forward> action enables you to forward the request to a static HTML file, a servlet, or another JSP.
<jsp:forward page="url" />The JSP that contains the <jsp:forward> action stops processing, clears its buffer, and forwards the request to the target resource. Note that the calling JSP should not write anything to the response prior to the <jsp:forward> action.
You can also pass additional parameters to the target resource using the <jsp:param> tag.
<jsp:forward page="test.htm" > <jsp:param name="name1" value="value1" /> <jsp:param name="name2" value="value2" /> </jsp:forward>
In this example, test.jsp can access the value of name1
using request.getParameter("name1")
.
To "include" another resource with a JSP, you have two options: the include directive and the include action.
The include directive executes when the JSP is compiled, which parses any JSP elements in the included file
for a static result that is the same for every instance of that JSP. The syntax for the include directive is
<@ include file="some-filename" %>
.
The include action, on the other hand, executes for each client request of the JSP, which means the file is not
parsed but included in place. This provides the capability to dynamically change not only the content that you want to include,
but also the output of that content. The syntax for the include action is
<jsp:include page="some-filename" flush="true" />
. Note that the flush attribute must always
be included (in JSP 1.1) to force a flush of the buffer in the output stream.
You can also pass parameters to the included file using the same process as the <jsp:forward> action:
<jsp:include page="template.htm" flush="true" > <jsp:param name="name1" value="value1" /> </jsp:include>Remember that template.jsp can access the value of
name1
using request.getParameter("name1")
.
To take full advantage of JSP technology, you can combine request delegation from servlets (or other JSPs) with a final "presentation" JSP that makes use of SAS Custom Tags. Not only does this help you maintain a separation between your business logic and presentation code, but it also can help your Web team separate the development roles of a Java developer and a Web designer.
Consider an example where you use a servlet to set up a connection to a SAS server and access a particular SAS table, then forward the request to a presentation JSP.
ShowTable Servlet:
import com.sas.sasserver.dataset.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ShowTable extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Setup the connection to SAS com.sas.rmi.Rocf rocf = new com.sas.rmi.Rocf(); com.sas.rmi.Connection connection = new com.sas.rmi.Connection(); connection.setHost("localhost"); // Set the dataset model to the SASHELP.SHOES table try { DataSetInterface dataset = (DataSetInterface) rocf.newInstance(DataSetInterface.class, connection); dataset.setDataSet("SASHELP.SHOES"); RequestDispatcher rd = getServletContext().getRequestDispatcher("/table.htm"); // Bind the dataset object to the request request.setAttribute("dataset", dataset); // Delegate the request to table.jsp rd.forward(request, response); } catch (Exception ex) { } } }
table.jsp:
<%@ page language="Java" errorPage="errorPage.htm" %> <%@ taglib uri="http://www.sas.com/sas-taglib/transforms" prefix="sasads" %> <HTML> <BODY> <P>Here is the table:</P> <sasads:Table id="table" model="<%= request.getAttribute("dataset") %>" useColumnHeadings="true" borderWidth="1" cellSpacing="2" cellPadding="1" renderType="html"> <sasads:RowFormat table="table" startRow="1" repeatRow="2"> <TR BGCOLOR="green"> <TD>#1#</TD><TD>#2#</TD><TD>#3#</TD> <TD>#4#</TD><TD>#5#</TD> </TR> </sasads:RowFormat> </sasads:Table> </BODY> </HTML>