craigmcc 01/03/10 18:50:13
Modified: src/conf struts-config_1_0.dtd
src/doc release-notes-1.0-b2.xml
src/example/org/apache/struts/example
ApplicationResources.properties
src/share/org/apache/struts/action ActionMapping.java
ActionResources.properties ActionServlet.java
web/example index.jsp
web/example/WEB-INF struts-config.xml
Log:
Add a new capability to the controller servlet framework -- the ability to
specify an external servlet or JSP resource (called by
RequestDispatcher.include()), instead of an Action class, as the ultimate
processor of an incoming request. This is done by specifying the new
"include" attribute, rather than the "type" attribute, on an <action>.
It is assumed that the included resource will have generated the
corresponding response (either directly, or by forwarding to some other
resource on its own). Therefore, no forwarding via a <forward> element is
performed after the included resource returns. This is equivalent to an
Action class that returns null from the perform() method.
If you specify a form bean in your <action> element, the standard form
bean processing (including calling the validate() method) is still
performed prior to including the requested resource. Therefore, you can
integrate existing servlet-based technologies into the Struts framework,
and still take advantage of the Struts form bean processing, without
having to create Action wrappers around the existing resources.
The include capability also opens the door to experimentation around
"scripting" of actions via JSP pages -- using Struts logic and bean
manipulation tags, other scripting languages via the BSF tag library in
the Jakarta Taglibs project <http://jakarta.apache.org/taglibs>, or
servlet based workflow and content management solutions that are not
necessarily tightly integrated with the Struts framework.
Revision Changes Path
1.13 +11 -3 jakarta-struts/src/conf/struts-config_1_0.dtd
Index: struts-config_1_0.dtd
===================================================================
RCS file: /home/cvs/jakarta-struts/src/conf/struts-config_1_0.dtd,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- struts-config_1_0.dtd 2001/02/21 00:19:08 1.12
+++ struts-config_1_0.dtd 2001/03/11 02:50:07 1.13
@@ -11,7 +11,7 @@
"-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">
- $Id: struts-config_1_0.dtd,v 1.12 2001/02/21 00:19:08 craigmcc Exp $
+ $Id: struts-config_1_0.dtd,v 1.13 2001/03/11 02:50:07 craigmcc Exp $
-->
@@ -265,6 +265,11 @@
configured as the "mapping" initialization parameter
to the Struts controller servlet.
+ include Context-relative path of the servlet or JSP resource that
+ will process this request, instead of instantiating and
+ calling the Action class specified by "type". Exactly one
+ of "include" and "type" must be specified.
+
input Context-relative path of the input form to which control
should be returned if a validation error is encountered.
Required if "name" is specified and the input bean
@@ -293,7 +298,9 @@
type Fully qualified Java class name of the Action class
(implements org.apache.struts.action.Action) to be
- used to process requests for this mapping.
+ used to process requests for this mapping if the "include"
+ attribute is not included. Exactly one of "include" and
+ "type" must be specified.
unknown Set to "true" if this action should be configured as the
default for this application, to handle all requests
@@ -308,13 +315,14 @@
<!ATTLIST action id ID #IMPLIED>
<!ATTLIST action attribute %BeanName; #IMPLIED>
<!ATTLIST action className %ClassName; #IMPLIED>
+<!ATTLIST action include %RequestPath; #IMPLIED>
<!ATTLIST action input %RequestPath; #IMPLIED>
<!ATTLIST action name %BeanName; #IMPLIED>
<!ATTLIST action path %RequestPath; #REQUIRED>
<!ATTLIST action prefix CDATA #IMPLIED>
<!ATTLIST action scope %RequestScope; #IMPLIED>
<!ATTLIST action suffix CDATA #IMPLIED>
-<!ATTLIST action type %ClassName; #REQUIRED>
+<!ATTLIST action type %ClassName; #IMPLIED>
<!ATTLIST action unknown %Boolean; "false">
<!ATTLIST action validate %Boolean; "true">
1.7 +13 -1 jakarta-struts/src/doc/release-notes-1.0-b2.xml
Index: release-notes-1.0-b2.xml
===================================================================
RCS file: /home/cvs/jakarta-struts/src/doc/release-notes-1.0-b2.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- release-notes-1.0-b2.xml 2001/03/11 00:58:41 1.6
+++ release-notes-1.0-b2.xml 2001/03/11 02:50:08 1.7
@@ -29,6 +29,18 @@
deprecated, and have been replaced (and considerably enhanced) in
the various individual tag libraries.</p>
+ <p>The following new features have been added to the basic controller
+ framework (package <code>org.apache.struts.action</code>):</p>
+ <ul>
+ <li>You can now specify that an <code><action></code> element should
+ invoke an existing servlet or JSP page resource, rather than calling an
+ <code>Action</code> class, by using the <code>include</code> attribute
+ rather than the <code>type</code> attribute. The standard form bean
+ processing provided by the controller is still performed first, if you
+ have configured it, so the included resource can benefit from this
+ processing if it wishes to.</li>
+ </ul>
+
<p>The following new features have been added to the
<em>struts-html</em> custom tag library (package
<code>org.apache.struts.taglib.html</code>):</p>
@@ -114,7 +126,7 @@
<li>Excessive filter() calls in <code>LinkSubscriptionTag</code>
have been eliminated.</li>
<li>Calls to the deprecated <code>BeanUtils.filter()</code> have been
- replaced by calls to <code>ResponseUtils.filter(</code>.</li>
+ replaced by calls to <code>ResponseUtils.filter()</code>.</li>
</ul>
</section>
1.7 +1 -0
jakarta-struts/src/example/org/apache/struts/example/ApplicationResources.properties
Index: ApplicationResources.properties
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/example/org/apache/struts/example/ApplicationResources.properties,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ApplicationResources.properties 2001/02/23 22:06:19 1.6
+++ ApplicationResources.properties 2001/03/11 02:50:09 1.7
@@ -32,6 +32,7 @@
index.logon=Log on to the MailReader Demonstration Application
index.registration=Register with the MailReader Demonstration Application
index.title=MailReader Demonstration Application (Struts 1.0-b1)
+index.tour=A Walking Tour of the Example Application
linkSubscription.io=I/O Error: {0}
linkSubscription.noSubscription=No subscription under attribute {0}
linkUser.io=I/O Error: {0}
1.15 +48 -5
jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java
Index: ActionMapping.java
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- ActionMapping.java 2001/03/06 22:15:13 1.14
+++ ActionMapping.java 2001/03/11 02:50:09 1.15
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v 1.14
2001/03/06 22:15:13 craigmcc Exp $
- * $Revision: 1.14 $
- * $Date: 2001/03/06 22:15:13 $
+ * $Header:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v 1.15
2001/03/11 02:50:09 craigmcc Exp $
+ * $Revision: 1.15 $
+ * $Date: 2001/03/11 02:50:09 $
*
* ====================================================================
*
@@ -108,6 +108,12 @@
* instead</em>.
* <li><strong>forwards</strong> - The set of ActionForwards locally
* associated with this mapping.
+ * <li><strong>include</strong> - Context-relative path of the resource that
+ * should serve this request (via a call to
+ * <code>RequestDispatcher.include()</code>) instead of instantiating the
+ * specified Action class specified by the <code>type</code> property.
+ * Exactly one of the <code>include</code> and <code>type</code> properties
+ * must be specified.</li>
* <li><strong>input</strong> - Context-relative path of the input form
* to which control should be returned if a validation error is
* encountered. Replaces the old <code>inputForm</code> property.
@@ -133,7 +139,9 @@
* bean (if any). Replaces the old <code>formSuffix</code> property.
* <li><strong>type</strong> - Fully qualified Java class name of the
* <code>Action</code> implementation class used by this mapping.
- * Replaces the old <code>actionClass</code> property.
+ * Replaces the old <code>actionClass</code> property. Exactly one of
+ * the <code>include</code> and <code>type</code> properties must be
+ * specified.</li>
* <li><strong>unknown</strong> - Set to <code>true</code> if this action
* should be configured as the default for this application, to handle
* all requests not handled by another action. Only one action can be
@@ -144,7 +152,7 @@
* </ul>
*
* @author Craig R. McClanahan
- * @version $Revision: 1.14 $ $Date: 2001/03/06 22:15:13 $
+ * @version $Revision: 1.15 $ $Date: 2001/03/11 02:50:09 $
*/
public class ActionMapping implements Serializable {
@@ -167,6 +175,15 @@
/**
+ * The context relative path of the servlet or JSP resource (to be called
+ * via <code>RequestDispatcher.include()</code>) that will process this
+ * request, rather than instantiating and calling the Action class that is
+ * specified by the <code>type</code> attribute.
+ */
+ protected String include = null;
+
+
+ /**
* The context-relative path of the input form to which control should
* be returned if a validation error is encountered.
*/
@@ -428,6 +445,28 @@
/**
+ * Return the include path for this mapping.
+ */
+ public String getInclude() {
+
+ return (this.include);
+
+ }
+
+
+ /**
+ * Set the include path for this mapping.
+ *
+ * @param include The include path for this mapping
+ */
+ public void setInclude(String include) {
+
+ this.include = include;
+
+ }
+
+
+ /**
* Return the input form path for this mapping.
*/
public String getInput() {
@@ -792,6 +831,10 @@
StringBuffer sb = new StringBuffer("ActionMapping[path=");
sb.append(path);
+ if (include != null) {
+ sb.append(", include=");
+ sb.append(include);
+ }
if (type != null) {
sb.append(", type=");
sb.append(type);
1.7 +2 -0
jakarta-struts/src/share/org/apache/struts/action/ActionResources.properties
Index: ActionResources.properties
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionResources.properties,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ActionResources.properties 2000/12/27 00:16:02 1.6
+++ ActionResources.properties 2001/03/11 02:50:10 1.7
@@ -11,8 +11,10 @@
destroyDataSource=Exception destroying application data source {0}
finalizing=Finalizing this controller servlet
initDataSource=Exception initializing application data source {0}
+mappingType=Must specify either "include" or "type" attribute for path {0}
noInput=No input attribute for mapping path {0}
processInvalid=Invalid path {0} was requested
processPath=No process path included in this request
reloading=Reloading from configuration files
+requestDispatcher=Cannot get request dispatcher for path {0}
sessionCreate=No user session could be created
1.63 +63 -4
jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java
Index: ActionServlet.java
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- ActionServlet.java 2001/02/23 21:13:09 1.62
+++ ActionServlet.java 2001/03/11 02:50:10 1.63
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.62
2001/02/23 21:13:09 craigmcc Exp $
- * $Revision: 1.62 $
- * $Date: 2001/02/23 21:13:09 $
+ * $Header:
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.63
2001/03/11 02:50:10 craigmcc Exp $
+ * $Revision: 1.63 $
+ * $Date: 2001/03/11 02:50:10 $
*
* ====================================================================
*
@@ -230,7 +230,7 @@
* </ul>
*
* @author Craig R. McClanahan
- * @version $Revision: 1.62 $ $Date: 2001/02/23 21:13:09 $
+ * @version $Revision: 1.63 $ $Date: 2001/03/11 02:50:10 $
*/
public class ActionServlet
@@ -561,6 +561,20 @@
*/
public void addMapping(ActionMapping mapping) {
+ // Validate that exactly one of "include" or "type" is included
+ int n = 0;
+ if (mapping.getInclude() != null)
+ n++;
+ if (mapping.getType() != null)
+ n++;
+ if (n != 1) {
+ String message =
+ internal.getMessage("mappingType", mapping.getPath());
+ log(message);
+ throw new IllegalArgumentException(message);
+ }
+
+ // Add this mapping to our global collection
mappings.addMapping(mapping);
}
@@ -1522,6 +1536,10 @@
if (!processValidate(mapping, formInstance, request, response))
return;
+ // Execute an include if specified by this mapping
+ if (!processInclude(mapping, request, response))
+ return;
+
// Acquire the Action instance to process this request
Action actionInstance = processActionCreate(mapping, request);
if (actionInstance == null) {
@@ -1740,6 +1758,47 @@
if (content != null)
response.setContentType(content);
+
+ }
+
+
+ /**
+ * Process an include requested by this mapping, if any. Return
+ * <code>true</code> if processing of this request should continue (i.e.
+ * be processed by an Action class), or <code>false</code> if we have
+ * already handled this request.
+ *
+ * @param mapping The ActionMapping we are processing
+ * @param request The request we are processing
+ * @param response The response we are processing
+ *
+ * @exception IOException if the included resource throws an exception
+ * @exception ServletException if the included resource throws an
+ * exception
+ */
+ protected boolean processInclude(ActionMapping mapping,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws IOException, ServletException {
+
+ // Are we going to process this request?
+ String include = mapping.getInclude();
+ if (include == null)
+ return (true);
+
+ // Construct a request dispatcher for the specified path
+ RequestDispatcher rd =
+ getServletContext().getRequestDispatcher(include);
+ if (rd == null) {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ internal.getMessage("requestDispatcher",
+ include));
+ return (false);
+ }
+
+ // Delegate the processing of this request
+ rd.include(request, response);
+ return (false);
}
1.16 +4 -1 jakarta-struts/web/example/index.jsp
Index: index.jsp
===================================================================
RCS file: /home/cvs/jakarta-struts/web/example/index.jsp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- index.jsp 2001/02/07 23:10:47 1.15
+++ index.jsp 2001/03/11 02:50:11 1.16
@@ -32,7 +32,10 @@
</ul>
<p> </p>
-<p><a target="_blank" href="tour.htm"><font size="1">A Walking Tour of the Example
Application</font></a></p>
+<html:link page="/tour.do">
+<font size="-1"><bean:message key="index.tour"/></font>
+</html:link>
+<p> </p>
<html:img page="/struts-power.gif" alt="Powered by Struts"/>
1.7 +5 -0 jakarta-struts/web/example/WEB-INF/struts-config.xml
Index: struts-config.xml
===================================================================
RCS file: /home/cvs/jakarta-struts/web/example/WEB-INF/struts-config.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- struts-config.xml 2000/12/27 00:16:03 1.6
+++ struts-config.xml 2001/03/11 02:50:12 1.7
@@ -113,6 +113,11 @@
</action>
+ <!-- Display the "walking tour" documentation -->
+ <action path="/tour"
+ include="/tour.htm">
+ </action>
+
<!-- The standard administrative actions available with Struts -->
<!-- These would be either omitted or protected by security -->
<!-- in a real application deployment -->