|
|
Name | Type | Required | Default | Purpose |
---|---|---|---|---|
contentType | String | No | text/html;charset=ISO-8859-1 | The content type to write to the response. See the document for javax.servlet.ServletResponse for more information. |
name | String | No | null | The name of this view. Purely for diagnostic purposes. |
staticAttributesCSV | String | No | null | CSV format string defining the static attributes associated with this view. Used in the deault properties view definition syntax. See example above. |
staticAttributes | java.until.Properties | No | n/a | Properties value defining the static attributes associated with theis view. Used if defining views in XML bean definitions (the CSV form is used when defining views in properties files, as it's problematic to have a property value that is itself in properties syntax. |
Let's begin by considering JSP, the commonest view technology in J2EE web applications.
As JSP 1.2 is part of the J2EE 1.3 specification, it's guaranteed to come with our application server.
However, we do need to include the JSTL libraries.
The sample application uses the Apache Jakarta implementation of the JSTL, available from http://jakarta.apache.org/taglibs. The following JARs from the /lib directory of the Jakarta JSTL distribution are required for using the tags shown in the sample application:
jstl.jar
standard.jar
sax.jar
saxpath.jar
jaxen-full.jar
The first two JARs define the JSTL API and the implementation of the standard tags; the last three are required by the implementation of the XML tags.
These files are included in the /lib/runtime/jsp-stl directory of the download, and automatically copied to the WEB-INF/lib directory of web applications build by the sample application's Ant build script.
We don't need to include the JSTL TLDs in WARs using it. We can simply import JSTL libraries using their published URLs atjava.sun.com, as in the following example, which imports the core library:
<%@ taglib prefix="c" url="http://java.sun.com/jstl/core" %>
Important | All applications using JSP should use the JSTL, which greatly improves the JSP authoring model. Thus the JSTL binaries should be included with all JSP-based applications. |
Let's now look at the framework's implementation of the View interface for use with JSP. The complete listing for this framework implementation can be found in the framework code accompanying the sample application, in the com.interface21.web.servlet.view.InternalResourceView class. The class is named InternalResourceView, rather than JspView, as it can be used for static HTML or servlets within the web application, as well as JSP.
This view implementation copies model entries to request attributes, before using a Servlet API RequestDispatcher to forward to the specified resource within the current web application, identified by a URL provided when the view is initialized.
By extending the com.interface21.web.servlet.view.AbstractView superclass the InternalResourceView class is required to implement only the renderMergedOutputModel() protected abstract method and expose the bean properties necessary to configure view instances.
The following partial listing of the InternalResourceView class omits logging methods and useful functionality to include debug information in the request if the ControllerServlet has set a request attribute indicating that it's in debug mode.
The basic steps to wrap a JSP template are very simple. We will need an instance variable to hold the url property and a property setter to allow InternalResourceView beans to be configured:
public class InternalResourceView extends AbstractView { private String url; public void setUrl (String url) { this. url = url; }
The url bean property must be set to the path to a JSP within the current web application, such as /jsp/myJsp.jsp.
The implementation of the renderMergedOutputModel() method obtains a RequestDispatcher for the cached URL from the web container, and forwards the request to it, after exposing model data as request attributes:
public void renderMergedOutputModel (Map model, HttpServletRequest request, HttpServletResponse response) throws ServletException {
exposeModelsAsRequestAttributes (model, request);
try { request .getRequestDispatcher (getUrl() ) . forward (request, response) ; } catch (IOException ex) {
throw new ServletException ("Couldn't dispatch to JSP with url "' +
getUrl ( ) + "' in InternalResourceView with name "' + getName() + ""', ex) ; } }
The code to set model attributes as request parameters is refactored into a protected method, in case any subclasses wish to reuse it:
protected final void exposeModelsAsRequestAttributes ( Map model, HttpServletRequest request) { if (model != null) { Set keys = model .keySet(); Iterator itr = keys . iterator(); while (itr.hasNext() ) { String modelname = (String) itr. next(); Object val = model .get (modelname) ; request . setAttribute (modelname, val) ; } } }
This standard view implementation can be used to wrap any JSP page, servlet, or static content from the same web application. It is not usually necessary to provide application-specific subclasses.
A typical view definition in /WEB-INF/classes/views.properties using the InternalResourceView class will look as follows:
showReservation.class=com.interface21.web.servlet.view.InternalResourceView showReservation.url=/showReservation.jsp
The only bean property exposed by InternalResourceView, beyond those inherited from AbstractView, is url. This property must be set to a resource URL within the WAR, as shown above. The URL may be under the WAR's /WEB-INF directory, as in the following example:
showReservation.class=com.interface21.web.servlet.view.InternalResourceView showReservation.url=/WEB-INF/jsps/protectedJsp.jsp
Resources under the special /WEB-INF directory are still accessible to RequestDispatchers, but are protected from direct user requests.
|
|