Modified: portals/site-live/bridges/bridges-struts/features.html URL: http://svn.apache.org/viewvc/portals/site-live/bridges/bridges-struts/features.html?rev=1901429&r1=1901428&r2=1901429&view=diff ============================================================================== --- portals/site-live/bridges/bridges-struts/features.html (original) +++ portals/site-live/bridges/bridges-struts/features.html Tue May 31 02:19:06 2022 @@ -1,690 +1,742 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - - - - - - - - - - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>Apache Portals Bridges - Struts Bridge Features</title> - <style type="text/css" media="all"> - @import url("../css/maven-base.css"); - @import url("../css/maven-theme.css"); - @import url("../css/site.css"); - </style> - <link rel="stylesheet" href="../css/print.css" type="text/css" media="print" /> - <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> - </head> - <body class="composite"> - <div id="banner"> - <a href="http://portals.apache.org/" id="bannerLeft"> - - <img src="../images/apache-portals.gif" alt="" /> - - </a> - <a href="http://portals.apache.org/bridges/" id="bannerRight"> - - Apache Portals Bridges - - </a> - <div class="clear"> - <hr/> - </div> - </div> - <div id="breadcrumbs"> - - - - - - - - - <div class="xleft"> - Last Published: 29 September 2011 - </div> - <div class="xright"> <a href="http://portals.apache.org/" class="externalLink">Portals</a> - | - <a href="http://portals.apache.org/applications" class="externalLink">Applications</a> - | - <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> - | - <a href="http://www.jcp.org/en/jsr/detail?id=168" class="externalLink">JSR-168</a> - | - <a href="http://www.jcp.org/en/jsr/detail?id=286" class="externalLink">JSR-286</a> - - - - - - - - - </div> - <div class="clear"> - <hr/> - </div> - </div> - <div id="leftColumn"> - <div id="navcolumn"> - - - - - - +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- Generated by Apache Maven Doxia Site Renderer 1.4 at 26 May 2022 --> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title>Apache Portals Bridges - + Struts Bridge Features</title> + <style type="text/css" media="all"> + @import url("../css/maven-base.css"); + @import url("../css/maven-theme.css"); + @import url("../css/site.css"); + </style> + <link rel="stylesheet" href="../css/print.css" type="text/css" media="print" /> + <meta name="Date-Revision-yyyymmdd" content="20220526" /> + <meta http-equiv="Content-Language" content="en" /> + + </head> + <body class="composite"> + <div id="banner"> + <a href="http://portals.apache.org/" id="bannerLeft"> + <img src="../images/apache-portals.gif" alt="Apache Software Foundation" /> + </a> + <a href="http://portals.apache.org/bridges/" id="bannerRight"> + Apache Portals Bridges + </a> + <div class="clear"> + <hr/> + </div> + </div> + <div id="breadcrumbs"> + + + <div class="xleft"> + <span id="publishDate">Last Published: 26 May 2022</span> + | <span id="projectVersion">Version: 1.0</span> + </div> + <div class="xright"> <a href="http://portals.apache.org/" class="externalLink" target="_nw" title="Portals">Portals</a> + | + <a href="http://portals.apache.org/applications" class="externalLink" target="_nw" title="Applications">Applications</a> + | + <a href="http://portals.apache.org/jetspeed-2" class="externalLink" target="_nw" title="Jetspeed-2">Jetspeed-2</a> + | + <a href="http://www.jcp.org/en/jsr/detail?id=168" class="externalLink" target="_nw" title="JSR-168">JSR-168</a> + | + <a href="http://www.jcp.org/en/jsr/detail?id=286" class="externalLink" target="_nw" title="JSR-286">JSR-286</a> + + + </div> + <div class="clear"> + <hr/> + </div> + </div> + <div id="leftColumn"> + <div id="navcolumn"> + + + <h5>Portals Bridges</h5> + <ul> + <li class="none"> + <a href="../index.html" title="Overview">Overview</a> + </li> + <li class="none"> + <a href="../news.html" title="News and Status">News and Status</a> + </li> + </ul> + <h5>Current Portals Bridges</h5> + <ul> + <li class="none"> + <a href="../bridges-common/index.html" title="Common Utilities and Interfaces">Common Utilities and Interfaces</a> + </li> + <li class="expanded"> + <a href="../bridges-struts/index.html" title="Struts Bridge">Struts Bridge</a> + <ul> + <li class="none"> + <strong>Features</strong> + </li> + </ul> + </li> + <li class="none"> + <a href="../bridges-velocity/index.html" title="Velocity Bridge">Velocity Bridge</a> + </li> + <li class="none"> + <a href="../bridges-script/index.html" title="Script Bridge">Script Bridge</a> + </li> + <li class="collapsed"> + <a href="../bridges-groovy/index.html" title="Groovy Bridge">Groovy Bridge</a> + </li> + </ul> + <h5>Archived Portals Bridges</h5> + <ul> + <li class="collapsed"> + <a href="../bridges-jsf/index.html" title="JSF Bridge">JSF Bridge</a> + </li> + <li class="collapsed"> + <a href="../bridges-php/index.html" title="PHP Bridge">PHP Bridge</a> + </li> + <li class="none"> + <a href="../bridges-perl/index.html" title="Perl Bridge">Perl Bridge</a> + </li> + <li class="none"> + <a href="../bridges-portletfilter/index.html" title="Portlet Filter">Portlet Filter</a> + </li> + </ul> + <h5>Get Portals Bridges</h5> + <ul> + <li class="none"> + <a href="../download.html" title="Download">Download</a> + </li> + <li class="none"> + <a href="../release-notes.html" title="Release Notes">Release Notes</a> + </li> + </ul> + <h5>Support</h5> + <ul> + <li class="none"> + <a href="../team-list.html" title="Project Team">Project Team</a> + </li> + <li class="none"> + <a href="../license.html" title="Project License">Project License</a> + </li> + <li class="none"> + <a href="../mail-lists.html" title="Mailing List">Mailing List</a> + </li> + <li class="none"> + <a href="../issue-tracking.html" title="Issue Tracking">Issue Tracking</a> + </li> + </ul> + <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"> + <img class="poweredBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /> + </a> + + + </div> + </div> + <div id="bodyColumn"> + <div id="contentBox"> + <!-- Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. --> - - <h5>Portals Bridges</h5> - <ul> - - <li class="none"> - <a href="../index.html">Overview</a> - </li> - - <li class="none"> - <a href="../news.html">News and Status</a> - </li> - </ul> - <h5>Current Portals Bridges</h5> - <ul> - - <li class="none"> - <a href="../bridges-common/index.html">Common Utilities and Interfaces</a> - </li> - - - - - - <li class="expanded"> - <a href="../bridges-struts/index.html">Struts Bridge</a> - <ul> - - <li class="none"> - <strong>Features</strong> - </li> - </ul> - </li> - - <li class="none"> - <a href="../bridges-velocity/index.html">Velocity Bridge</a> + <div class="section"> +<h2>Features<a name="Features"></a></h2> + +<p> + The Struts Bridge provides the following features for developing and running Struts Applications as Portlets: + </p> +<ul> + +<li> + <a href="#Struts_Page_URL"> + Provides a "virtual" page context and a "normal" page url to the Struts Application + </a> </li> - - <li class="none"> - <a href="../bridges-script/index.html">Script Bridge</a> + +<li> + <a href="#The_ServletContextProvider_interface"> + Allows Servlet invocation from an ActionRequest using an separate lightweight interface to the Portal + </a> </li> - - - - - - - - <li class="collapsed"> - <a href="../bridges-groovy/index.html">Groovy Bridge</a> - </li> - </ul> - <h5>Archived Portals Bridges</h5> - <ul> - - - - - - - - <li class="collapsed"> - <a href="../bridges-jsf/index.html">JSF Bridge</a> - </li> - - - - - - - - - - <li class="collapsed"> - <a href="../bridges-php/index.html">PHP Bridge</a> - </li> - - <li class="none"> - <a href="../bridges-perl/index.html">Perl Bridge</a> + +<li> + <a href="#Portals_requiring_a_more_complex_interface"> + Provides extension points if a more complex interface to the Portal is required + </a> </li> - - <li class="none"> - <a href="../bridges-portletfilter/index.html">Portlet Filter</a> + +<li> + <a href="#Handling_ActionRequests"> + Automatically separates Struts Action Processing and View Rendering when accessed from an ActionRequest + </a> </li> - </ul> - <h5>Get Portals Bridges</h5> - <ul> - - <li class="none"> - <a href="../download.html">Download</a> + +<li> + <a href="#RenderContextAttributes_to_the_rescue"> + Transparent communication of request attributes between ActionRequest and RenderRequests + </a> </li> - - <li class="none"> - <a href="../release-notes.html">Release Notes</a> + +<li> + <a href="#Rendering_valid_Portlet_urls_with_the_Struts_JSP_Tags"> + Transparent translation of "normal" Web application resource and action link urls to valid Portlet urls + </a> </li> - </ul> - <h5>Support</h5> - <ul> - - <li class="none"> - <a href="../team-list.html">Project Team</a> + +<li> + <a href="#PortletRequestProcessor_and_PortletTilesRequestProcessor"> + Tiles support and automatic configuration of the correct (Portlet)RequestProcessor (enhanced for 1.0.1) + </a> </li> - - <li class="none"> - <a href="../license.html">Project License</a> + +<li> + <a href="#Running_your_application_as_Portlet_and_Web_Application_at_the_same_time"> + Deploy and run Struts Applications as Portlet and as Web Application at the same time + </a> </li> - - <li class="none"> - <a href="../mail-lists.html">Mailing List</a> + +<li> + <a href="#a1.0.1:_Multiple_StrutsPortlet_instances_PORTLET_SCOPE_isolated_StrutsServlet_sessions"> + 1.0.1: Multiple StrutsPortlet instances with the StrutsServlet session isolated to PORTLET_SCOPE + </a> </li> - - <li class="none"> - <a href="../issue-tracking.html">Issue Tracking</a> + + + +<li> + Supports Struts release 1.2.7 </li> - </ul> - <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"> - <img alt="Built by Maven" src="../images/logos/maven-feather.png"></img> - </a> - - - - - - - - - </div> - </div> - <div id="bodyColumn"> - <div id="contentBox"> - <subtitle></subtitle><authors><person name="Ate Douma" email="[email protected]"></authors><div class="section"><h2><a name="Features"></a>Features</h2> -<p> - The Struts Bridge provides the following features for developing and running Struts Applications as Portlets: - <ul><li><a href="#Struts Page URL"> - Provides a "virtual" page context and a "normal" page url to the Struts Application - </a></li> -<li><a href="#The ServletContextProvider interface"> - Allows Servlet invocation from an ActionRequest using an separate lightweight interface to the Portal - </a></li> -<li><a href="#Portals requiring a more complex interface"> - Provides extension points if a more complex interface to the Portal is required - </a></li> -<li><a href="#Handling ActionRequests"> - Automatically separates Struts Action Processing and View Rendering when accessed from an ActionRequest - </a></li> -<li><a href="#RenderContextAttributes to the rescue"> - Transparent communication of request attributes between ActionRequest and RenderRequests - </a></li> -<li><a href="#Rendering valid Portlet urls with the Struts JSP Tags"> - Transparent translation of "normal" Web application resource and action link urls to valid Portlet urls - </a></li> -<li><a href="#PortletRequestProcessor and PortletTilesRequestProcessor"> - Tiles support and automatic configuration of the correct (Portlet)RequestProcessor (enhanced for 1.0.1) - </a></li> -<li><a href="#Running your application as Portlet and Web Application at the same time"> - Deploy and run Struts Applications as Portlet and as Web Application at the same time - </a></li> -<li><a href="#1.0.1: Multiple StrutsPortlet instances PORTLET_SCOPE isolated StrutsServlet sessions"> - 1.0.1: Multiple StrutsPortlet instances with the StrutsServlet session isolated to PORTLET_SCOPE - </a></li> -<li> - Supports Struts release 1.2.7 - </li> -</ul> -</p> -<div class="section"><h3><a name="Struts_Page_URL"></a>Struts Page URL</h3> -<p> - Struts determines the Actions to perform on the request url. A Portlet on the other hand doesn't - have or receive an url, only request parameters. - </p> -<p> - To be able to use Struts within a Portlet, a current Page context is maintained by the Struts Bridge - which is used to provide Struts with a "virtual" request context just as if it were accessed from a Web - Application. - </p> -<p> - The Struts Page URL is maintained as a Portlet <code>RenderParameter</code> and included in all Portlet URLs - generated for the Portlet. When the <code>StrutsPortlet</code> receives a request it uses the Struts Page URL - to create a new <code>HttpServletRequest</code> with a redefined request url before invoking the Struts - <code>PortletServlet</code> (extending the Struts <code>ActionServlet</code>). - </p> -<p> - None of the Action Mappings for an existing Struts Application have to be changed (in this respect at least) - to allow it to run in a Portlet context. - </p> -</div> -<div class="section"><h3><a name="The_ServletContextProvider_interface"></a>The ServletContextProvider interface</h3> -<p> - Processing <code>ActionRequest</code> and <code>RenderRequest</code> events from a Servlet application is a - problem with the current Portlet Specification. Although Servlets (and JSPs) can be invoked from a Portlet, - the Portlet Specification only supports this from the <code>RenderRequest</code>. - </p> -<p> - As request parameters are only available during the <code>ActionRequest</code>, not being able to use a Struts - for processing these is a serious limitation. Together with no clear inter-portlet application communication - support, this is probably one of the biggest omissions from the Portlet Specification. - </p> -<p> - But, because the Portlet Specification is build upon the Servlet Specification (2.3), the Portlet Container - implementation (like <a href="http://portals.apache.org/pluto" class="externalLink">Pluto</a>) and/or the Portal itself, usually - has direct access to, and also uses the <code>ServletContext</code>, even during the - <code>ActionRequest</code> event. - </p> -<p> - It is therefore usually quite easy to provide access to the <code>ServletContext</code>, although it will - require some knowledge of the Portal and/or the Portlet Container implementation. - </p> -<p> - The Struts Bridge uses the <code>ServletContextProvider</code> interface from the - portals-bridges-common library to get access to the required <code>ServletContext</code>. - </p> -<p> - To be able to use the Struts Bridge, a <code>StrutsPortlet</code> must therefore be provided with a concrete - implementation of the <code>ServletContextProvider</code> interface (through its initialization parameters). - This implementation class can be supplied together with the Portlet or be provided natively by the Portal as - the <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> Portal does. - </p> -</div> -<div class="section"><h3><a name="Portals_requiring_a_more_complex_interface"></a>Portals requiring a more complex interface</h3> -<p> - Although the <code>ServletContextProvider</code> interface has been defined to be easily implemented for a - specific Portal, it might not be generic enough for all. - </p> -<p> - To support those kind of Portals, the <code>StrutsPortlet</code> doesn't uses the interface directly, but only - through protected methods of its own which can be extended if needed. - </p> -</div> -<div class="section"><h3><a name="Handling_ActionRequests"></a>Handling ActionRequests</h3> -<p> - During an <code>ActionRequest</code> a Portlet (or invoked Servlet) is not allowed to write content to the - response. This is only allowed during the <code>RenderRequest</code> event but then a Portlet doesn't have - access anymore to the (input) request parameters which makes the RenderRequest generally useless (and bad - practice anyway) for (Struts) Action processing. - </p> -<p> - Struts on the other hand only knows one request event and is largely build upon server-side forwarding to a - JSP (or other View rendering technology) after an Action has been processed. - </p> -<p> - The Struts Bridge solves this problem by allowing Struts Action processing to occur during the ActionRequest. - But, as soon as Struts forwards (or includes) to another handler (JSP, Velocity script, <em>or even another - Action: ActionChaining</em>) it will intercept and freeze the processing.<br /> - - The Struts Bridge will then save the current processing context (like the path to include or forward to) in a - separate object: the <code>StrutsRenderContext</code>, and end the ActionRequest.<br /> - - Once the RenderRequest is invoked, the Struts Bridge will use the <code>StrutsRenderContext</code> to restore - the state Struts (and/or an included or forwarded JSP) will expect and continues the processing where it left - off. - </p> -<p> - Also saved in the StrutsRenderContext are the current <code>ActionForm</code> (if it isn't already session - bounded), the <code>ActionMessages</code> and/or <code>ActionErrors</code> (if not already session bounded - which is possible since Struts 1.2.1). - </p> -<p><b><em>Important:</em></b> the StrutsRenderContext is restored only once! - </p> -<p> - The Portlet Specification expects Portlets to use a true MVC architecture: changing the state of a Portlet is - expected to be done during ActionRequest only. The RenderRequest, which may occur many times, is expected to - only render the current state of the Portlet. - </p> -<p> - For a proper usage of the Struts Bridge and to conform to the Portlet Specification requirements, the Struts - application too really should be configured to use separate Action processing and View rendering Actions.<br /> -</p> -<p> - The dependency on the StrutsRenderContext restoring the state during the (next) RenderRequest should be - limited to one situation only: input error processing. - </p> -<p> - When Struts encounters input validation errors, it forwards (back) to the page specified as input for the - Action. The Struts Bridge handles this situation likewise. When it detects ActionErrors are defined after the - ActionRequest event, it will reset the Struts Page URL to the one from which the ActionRequest was initiated - so subsequent (multiple) RenderRequest events will always render that original page. - </p> -<p> - Note: this will only result the same behavior as when the Struts Application is accessed as Web Application if - the Action Mapping input attribute indeed points to the originating input page, which normally will be the - case. <em>The Struts Bridge will not (re)set the Struts Page URL to the Action input attribute value (Struts - itself will forward to that url) but to the page from which the ActionRequest was initiated!</em></p> -<p> - As said, for a proper usage of the Struts Bridge the Struts application should be configured to use separate - Action processing and View processing Actions. The Struts Bridge intercepts the first include or forward - initiated from a Struts Action during the ActionRequest. During only the first following RenderRequest it will - invoke Struts with <em>the same Struts Page URL</em> as for the ActionRequest but intercept before the actual - execution of the mapped Action and then include (never forward) the intercepted target url of the ActionRequest - (normally a JSP). - </p> -<p> - A properly MVC configured Struts application though can (and should) make use of a (client-side) redirect - after the Action processing Action by using an ActionForward with redirect="true". The behavior of such a - Struts Application then truly complies to the requirements for a Portlet. In fact, the reference - implementation of the Portlet Specification, <a href="http://portals.apache.org/pluto" class="externalLink">Pluto</a>, actually - sends a redirect to the client (browser) after an ActionRequest. - </p> -<p> - The Struts Bridge supports this behavior as it will intercept a client-side redirect during an ActionRequest - by changing the Portlet Page URL to be used by subsequent RenderRequests to the targeted redirect url. - </p> -<p> - A Struts Application not complying to the above "rules" might not behave as expected in a Portlet context:<br /> - - without this configuration a second RenderRequest event will not get the previously saved StrutsRenderContext - restored and the invoked Struts Action will be executed again (this time without any parameters). - </p> -<p> - Migrating an existing Struts Application to a Struts Portlet with doesn't comply to these "rules" might seem - problematic without major changes to the code, but it doesn't have to be. - </p> -</div> -<div class="section"><h3><a name="RenderContextAttributes_to_the_rescue"></a>RenderContextAttributes to the rescue</h3> -<p> - Although a StrutsRenderContext can only be used once to communicate request parameters from the ActionRequest - to the next RenderRequest (stored in the ActionForm), the Struts Bridge provides another, completely - transparent, solution which can be used without any required changes to the Struts Application. - </p> -<p> - The Struts Bridge can be configured, using a simple xml definition, to always save specific named request - attributes during an ActionRequest and restore these only during the next RenderRequest or optionally every - RenderRequest until the next ActionRequest or a RenderRequest for a different Struts Page URL is invoked. - </p> -<p> - The request attribute values will be saved in the web session which requires them to implement the - <code>Serializable</code> interface. - </p> -<p> - An example struts-portlet-config.xml (the name of this file is configurable) definition might look like: - <div class="source"><pre> - <?xml version="1.0" encoding="UTF-8"?> - <config> - <render-context> - <attribute name="errors"/> - <attribute name="message" keep="true"/> - <attribute prefix="com.foo.bar" keep="true"/> - </render-context> - </config></pre> -</div> -<em>(This (adapted) example is taken from the JPetstore Portlet example provided with the - <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> Portal.)</em></p> -<p> - With the above example configuration, all request attributes named <em>errors</em> and <em>message</em> are - saved after the ActionRequest. The <em>errors</em> object is restored only once, the <em>message</em> object - will be restored until the next ActionRequest or when the Struts Page URL is changed. - </p> -<p> - Furthermore, every request attribute which name start with <em>com.foo.bar</em> is also saved after the ActionRequest. - With the "prefix" attribute type definition, a whole range of attributes can be configured at once. - </p> -<p> - Using the RenderContextAttributes configuration, a Struts Action can still forward (without redirecting) to a - JSP in a Portlet while passing its required data through the request attributes. Request scoped ActionForms - can also safely be used for this as the Struts Bridge will automatically remove them from the session again - when they go out of scope! - </p> -<p> - Using the "single use only" configuration (meaning: without the keep="true" attribute) allows one to pass on rather large - objects to the RenderRequest because, even if they are stored in the Session, this will only be for a very - short period (milliseconds). Of course, with a subsequent RenderRequest these objects won't be available - anymore and the specific View Renderer must be able to handle that situation properly.<br /> - - Error objects or error messages (other than ActionMessages and ActionErrors which are already automatically - saved in the StrutsRenderContext) are also reasonable candidates to use like this. - </p> -</div> -<div class="section"><h3><a name="Rendering_valid_Portlet_urls_with_the_Struts_JSP_Tags"></a>Rendering valid Portlet urls with the Struts JSP Tags</h3> -<p> - Another problem with using Struts for Portlet Development is rendering valid urls. - </p> -<p> - There are actually two different type of problems: urls for resources likes images, Javascript or CSS - stylesheets which needs to be loaded by the client (browser), and urls for interacting with the Portlet - itself. - </p> -<p> - The problem with resource urls is that the content of a Portlet is only included by the Portal, - together with possible content of other Portlets shown on the same page. Although the Portlet runs within - its own context (the same as the web application it is based on), the client (browser) sees only the context - of the Portal page it is currently pointed at. - </p> -<p> - A Portlet therefore cannot make use of relative src locations for a resource url while this is perfectly valid - (and usually preferred) in a Web Application. For a client to be able to retrieve a resource, its url - really must include the full context path of the Web Application. - </p> -<p> - For interacting with the Portlet special PortletURLs must be used which can only be generated using the - Portlet API or through the Portlet JSP Tags. The Struts JSP Tags only generate urls valid for a Web - Application and also doesn't provide some kind of URLProvider interface like JSF. - </p> -<p> - Furthermore there are two different PortletURL types: ActionURLs and RenderURLs. - It is very important to generate the correct type of url for a certain interaction. Forms must *always* use - a POST to an ActionURL, but for generated links it will have to be determined which type of url actually - is needed. - </p> -<p> - To solve these problems, the Struts Bridge provides enhanced versions of the Struts HTML JSP Tags (including - EL variants), which take the Portlet environment into account. Furthermore, using a separate element in - the struts-portlet-config.xml definition, specific url paths can be configured to be of a certain type - (Resource, ActionURL, RenderURL) only. - </p> -<p> - For the enhanced Struts HTML JSP Tags (html:form, html:link, html:rewrite, html:image and html:img), four - different TLDs are provided: an EL and non-EL variant, and for both a full replacement of the Struts - supplied struts-html.tld as well as a separate struts-portlet.tld containing only the enhanced Tags definitions. - </p> -<p> - The full replacement TLDs makes it very easy for migrating a Struts Application to a Portlet context: simply - map the new TLD in web.xml or redefine the taglib uri in the JSP using: - <div class="source"><pre> - <%@ taglib uri="http://portals.apache.org/bridges/struts/tags-portlet-html" prefix="html" %></pre> -</div> - - or - <div class="source"><pre> - <%@ taglib uri="http://portals.apache.org/bridges/struts/tags-portlet-html-el" prefix="html-el" %></pre> -</div> -<em>(Note: the Struts Bridge library contains all the TLDs so you don't need to add them yourself - somewhere under WEB-INF/.)</em></p> -<p> - For the enhanced html:link and html:rewrite Tags, three additional boolean attributes are defined: actionURL, - renderURL and resourceURL. Using these attributes one can specify which type of url must be generated (only - value "true" is supported). - </p> -<p> - If none of these attributes is specified (with value "true") these Tags will by default generate a RenderURL. - </p> -<p> - But, the default can be changed (only between renderURL and actionURL) using a struts-portlet-config.xml - definition. Furthermore, for specific url path (prefixes) you can specify which type of url must be generated - (but with one of the three additional boolean url type attributes this can always be overriden). - </p> -<p> - An example struts-portlet-config.xml with portlet url type definitions might look like: - <div class="source"><pre> - <?xml version="1.0" encoding="UTF-8"?> - <config> - <render-context> - <attribute name="errors"/> - <attribute name="message" keep="true"/> - </render-context> - <portlet-url-type> - <action path="/shop/add"/> - <action path="/shop/switch"/> - <action path="/shop/remove"/> - <action path="/shop/signoff"/> - <action path="/shop/viewCategory"/> - <action path="/shop/viewItem"/> - <action path="/shop/viewProduct"/> - <action path="/shop/viewCart"/> - <action path="/shop/newOrder"/> - <render path="/shop/newOrderForm"/> - <action path="/shop/listOrders"/> - <resource path="/images/"/> - </portlet-url-type> - </config></pre> -</div> -<em>(This is the full configuration used for the JPetstore Portlet example provided with the - <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> Portal.)</em></p> -<p> - In the above example the portlet-url-type element contains three different sub elements: action, render and - resource. Their path attribute specifies the prefix to which specific urls are matched. This matching will be - done using best match. Internally, the paths will be ordered on longest definition first. - </p> -<p> - Not shown in the above example is the optional default="render"|"action" attribute for the portlet-url-type - element. With it, the default type of portlet-url can be changed from "render" to "action" as is used in the - Struts Mailreader Demo Portlet (also provided by the <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> - Portal): - <div class="source"><pre> - <?xml version="1.0" encoding="UTF-8"?> - <config> - <portlet-url-type default="action"/> - </config></pre> -</div> - - This feature is especially useful for Struts Applications who were configured using an earlier version of - the Struts Bridge (0.1) which used an ActionURL as default, like the above Struts Mailreader Demo Portlet. - </p> -<p> - The enhanced html:img and html:image Tags, as well as the html:link and html:rewrite Tags, can be used to - generate resource urls using relative (not prefixed with a '/') src references. The Tags will then - automatically determine the correct url to generate using the current Struts Page URL as defined for this - RenderRequest. - </p> -<p> - This allows one to replace hard coded resource urls like - <div class="source"><pre><img src="../images/struts-bridge.gif"/></pre> -</div> - - with - <div class="source"><pre><html:image src="../images/struts-bridge.gif"/></pre> -</div> - - A simple change with no technical impact, but it will allow the same JSP to be used for both a Web Application - and a Portlet. The JPetstore Portlet example as provided by <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> - makes full use of this feature. - </p> -</div> -<div class="section"><h3><a name="PortletRequestProcessor_and_PortletTilesRequestProcessor"></a>PortletRequestProcessor and PortletTilesRequestProcessor</h3> -<p> - The Struts Bridge requires a different RequestProcessor to be used for the Struts Application: a <code> - PortletRequestProcessor</code>. If a Struts config doesn't define one, or defines one which isn't based on the - PortletRequestProcessor, it will be replaced automatically by the Struts Bridge. - </p> -<p> - The Struts Bridge also supports Tiles to be used with the <code>PortletTilesRequestProcessor</code>. If the - TilesPlugin is defined (as required to be able to use Tiles in Struts) it will be recognized by the Struts - Bridge and then the PortletTilesRequestProcessor will be used instead (if not configured already). - </p> -<p> - Tiles can be used without problem within a Portlet context, even for Action Mapping or ActionForward paths, - although the same considerations and restrictions must be taken into account as described above. - </p> -<p> - 1.0.1: For proper handling of the Tiles Context, with version 1.0 the Tiles ComponentConstants.COMPONENT_CONTEXT had to be - set as RenderContextAttribute like this: - <div class="source"><pre> - <?xml version="1.0" encoding="UTF-8"?> - <config> - <render-context> - <attribute name="org.apache.struts.taglib.tiles.CompContext"/> - ... - </render-context> - ... - </config></pre> -</div> - - With the 1.0.1 release, this isn't necessary anymore as the Struts Bridge will register this special attribute - itself automatically if it hasn't been defined in the struts-portlet-config.xml already. - </p> -</div> -<div class="section"><h3><a name="Running_your_application_as_Portlet_and_Web_Application_at_the_same_time"></a>Running your application as Portlet and Web Application at the same time</h3> -<p> - Although the Struts Bridge is created to allow Struts Applications to run in a Portlet context, it also allows - the same application to be run in a Servlet context too. - </p> -<p> - If the Struts Bridge PortletServlet (which extends ActionServlet) detects it is not accessed from a Portlet - context is simply delegates back to the underlying Struts Framework. - </p> -<p> - Provided the Struts Application doesn't use any Portlet specific features and the Action Mapping configuration - is also (still) valid for a Web Application, the same application war can be deployed as Web application and - as Portlet Application. When deployed in a Portal, the application can even be accessed as Portlet or as - Web Application at the same time! - </p> -<p> - The JPetstore Portlet example provided by <a href="http://portals.apache.org/jetspeed-2" class="externalLink">Jetspeed-2</a> is one - example of such a "dual" mode Struts Application. - </p> -<p> - Another benefit of such a "dual" mode Struts Application is that it can be tested as Web Application - which <em>is</em> somewhat easier than testing it as a Portlet. - </p> -</div> -<div class="section"><h3><a name="a1.0.1:_Multiple_StrutsPortlet_instances_PORTLET_SCOPE_isolated_StrutsServlet_sessions"></a>1.0.1: Multiple StrutsPortlet instances PORTLET_SCOPE isolated StrutsServlet sessions</h3> -<p> - The Struts framework itself, as well as many Struts applications make have use of the (Servlet) Session for storing user state. - When you want to use multiple StrutsPortlets from the same web application this can cause conflicts and session state corruption. - With Struts Bridge release 1.0.1, this now has been solved by (optionally, and not by default) isolating the Session scope - seen by the StrutsServlet to PortletSession.PORTLET_SCOPE. - </p> -<p> - If the optional StrutsPortlet init parameter <code>PortletScopeStrutsSession</code> is set to true, the Session object provided to the - StrutsServlet will be a Proxy for the PortletSession and will provide only access to the PortletSession.PORTLET_SCOPE attributes. - </p> -<p> - One caveat though: If you also need to use direct Servlet access to the Struts application (meaning: the browser is invoking the - Servlet directly, not through the Portlet), this Servlet won't "see" the previously APPLICATION_SCOPE Session attributes anymore.<br /> - - This can be an issue for features like binary file (pdf) rendering through a servlet which needs to use the Session to access its data. - To solve this, the utility - <a href="../portals-bridges-common/apidocs/org/apache/portals/bridges/util/PortletWindowUtils.html">PortletWindowUtils</a> class can - be used which provides methods to access a specific Portlet instance its PORTLET_SCOPE session attributes based on its PortletWindowId.<br /> - - That PortletWindowId (which a Portlet can retrieve itself using the PortletWindowUtils) needs to be passed on to the Servlet first - (for example as query-string parameter on a link send to the browser) for it to be able to make use of it. - </p> -</div> -</div> - - </div> - </div> - <div class="clear"> - <hr/> - </div> - <div id="footer"> - <div class="xright">© - 2004-2011 - - Apache Software Foundation + </ul> + + +<div class="section"> +<h3>Struts Page URL<a name="Struts_Page_URL"></a></h3> + +<p> + Struts determines the Actions to perform on the request url. A Portlet on the other hand doesn't + have or receive an url, only request parameters. + </p> + +<p> + To be able to use Struts within a Portlet, a current Page context is maintained by the Struts Bridge + which is used to provide Struts with a "virtual" request context just as if it were accessed from a Web + Application. + </p> + +<p> + The Struts Page URL is maintained as a Portlet <tt>RenderParameter</tt> and included in all Portlet URLs + generated for the Portlet. When the <tt>StrutsPortlet</tt> receives a request it uses the Struts Page URL + to create a new <tt>HttpServletRequest</tt> with a redefined request url before invoking the Struts + <tt>PortletServlet</tt> (extending the Struts <tt>ActionServlet</tt>). + </p> + +<p> + None of the Action Mappings for an existing Struts Application have to be changed (in this respect at least) + to allow it to run in a Portlet context. + </p> + </div> + +<div class="section"> +<h3>The ServletContextProvider interface<a name="The_ServletContextProvider_interface"></a></h3> + +<p> + Processing <tt>ActionRequest</tt> and <tt>RenderRequest</tt> events from a Servlet application is a + problem with the current Portlet Specification. Although Servlets (and JSPs) can be invoked from a Portlet, + the Portlet Specification only supports this from the <tt>RenderRequest</tt>. + </p> + +<p> + As request parameters are only available during the <tt>ActionRequest</tt>, not being able to use a Struts + for processing these is a serious limitation. Together with no clear inter-portlet application communication + support, this is probably one of the biggest omissions from the Portlet Specification. + </p> + +<p> + But, because the Portlet Specification is build upon the Servlet Specification (2.3), the Portlet Container + implementation (like <a class="externalLink" href="http://portals.apache.org/pluto" target="_nw">Pluto</a>) and/or the Portal itself, usually + has direct access to, and also uses the <tt>ServletContext</tt>, even during the + <tt>ActionRequest</tt> event. + </p> + +<p> + It is therefore usually quite easy to provide access to the <tt>ServletContext</tt>, although it will + require some knowledge of the Portal and/or the Portlet Container implementation. + </p> + +<p> + The Struts Bridge uses the <tt>ServletContextProvider</tt> interface from the + portals-bridges-common library to get access to the required <tt>ServletContext</tt>. + </p> + +<p> + To be able to use the Struts Bridge, a <tt>StrutsPortlet</tt> must therefore be provided with a concrete + implementation of the <tt>ServletContextProvider</tt> interface (through its initialization parameters). + This implementation class can be supplied together with the Portlet or be provided natively by the Portal as + the <a class="externalLink" href="http://portals.apache.org/jetspeed-2" target="_nw">Jetspeed-2</a> Portal does. + </p> + </div> + +<div class="section"> +<h3>Portals requiring a more complex interface<a name="Portals_requiring_a_more_complex_interface"></a></h3> + +<p> + Although the <tt>ServletContextProvider</tt> interface has been defined to be easily implemented for a + specific Portal, it might not be generic enough for all. + </p> + +<p> + To support those kind of Portals, the <tt>StrutsPortlet</tt> doesn't uses the interface directly, but only + through protected methods of its own which can be extended if needed. + </p> + </div> + +<div class="section"> +<h3>Handling ActionRequests<a name="Handling_ActionRequests"></a></h3> + +<p> + During an <tt>ActionRequest</tt> a Portlet (or invoked Servlet) is not allowed to write content to the + response. This is only allowed during the <tt>RenderRequest</tt> event but then a Portlet doesn't have + access anymore to the (input) request parameters which makes the RenderRequest generally useless (and bad + practice anyway) for (Struts) Action processing. + </p> + +<p> + Struts on the other hand only knows one request event and is largely build upon server-side forwarding to a + JSP (or other View rendering technology) after an Action has been processed. + </p> + +<p> + The Struts Bridge solves this problem by allowing Struts Action processing to occur during the ActionRequest. + But, as soon as Struts forwards (or includes) to another handler (JSP, Velocity script, <i>or even another + Action: ActionChaining</i>) it will intercept and freeze the processing.<br /> + The Struts Bridge will then save the current processing context (like the path to include or forward to) in a + separate object: the <tt>StrutsRenderContext</tt>, and end the ActionRequest.<br /> + Once the RenderRequest is invoked, the Struts Bridge will use the <tt>StrutsRenderContext</tt> to restore + the state Struts (and/or an included or forwarded JSP) will expect and continues the processing where it left + off. + </p> + +<p> + Also saved in the StrutsRenderContext are the current <tt>ActionForm</tt> (if it isn't already session + bounded), the <tt>ActionMessages</tt> and/or <tt>ActionErrors</tt> (if not already session bounded + which is possible since Struts 1.2.1). + </p> + +<p> + <b><i>Important:</i></b> the StrutsRenderContext is restored only once! + </p> + +<p> + The Portlet Specification expects Portlets to use a true MVC architecture: changing the state of a Portlet is + expected to be done during ActionRequest only. The RenderRequest, which may occur many times, is expected to + only render the current state of the Portlet. + </p> + +<p> + For a proper usage of the Struts Bridge and to conform to the Portlet Specification requirements, the Struts + application too really should be configured to use separate Action processing and View rendering Actions.<br /> + </p> + +<p> + The dependency on the StrutsRenderContext restoring the state during the (next) RenderRequest should be + limited to one situation only: input error processing. + </p> + +<p> + When Struts encounters input validation errors, it forwards (back) to the page specified as input for the + Action. The Struts Bridge handles this situation likewise. When it detects ActionErrors are defined after the + ActionRequest event, it will reset the Struts Page URL to the one from which the ActionRequest was initiated + so subsequent (multiple) RenderRequest events will always render that original page. + </p> + +<p> + Note: this will only result the same behavior as when the Struts Application is accessed as Web Application if + the Action Mapping input attribute indeed points to the originating input page, which normally will be the + case. <i>The Struts Bridge will not (re)set the Struts Page URL to the Action input attribute value (Struts + itself will forward to that url) but to the page from which the ActionRequest was initiated!</i> + </p> + +<p> + As said, for a proper usage of the Struts Bridge the Struts application should be configured to use separate + Action processing and View processing Actions. The Struts Bridge intercepts the first include or forward + initiated from a Struts Action during the ActionRequest. During only the first following RenderRequest it will + invoke Struts with <i>the same Struts Page URL</i> as for the ActionRequest but intercept before the actual + execution of the mapped Action and then include (never forward) the intercepted target url of the ActionRequest + (normally a JSP). + </p> + +<p> + A properly MVC configured Struts application though can (and should) make use of a (client-side) redirect + after the Action processing Action by using an ActionForward with redirect="true". The behavior of such a + Struts Application then truly complies to the requirements for a Portlet. In fact, the reference + implementation of the Portlet Specification, <a class="externalLink" href="http://portals.apache.org/pluto" target="_nw">Pluto</a>, actually + sends a redirect to the client (browser) after an ActionRequest. + </p> + +<p> + The Struts Bridge supports this behavior as it will intercept a client-side redirect during an ActionRequest + by changing the Portlet Page URL to be used by subsequent RenderRequests to the targeted redirect url. + </p> + +<p> + A Struts Application not complying to the above "rules" might not behave as expected in a Portlet context:<br /> + without this configuration a second RenderRequest event will not get the previously saved StrutsRenderContext + restored and the invoked Struts Action will be executed again (this time without any parameters). + </p> + +<p> + Migrating an existing Struts Application to a Struts Portlet with doesn't comply to these "rules" might seem + problematic without major changes to the code, but it doesn't have to be. + </p> + </div> + +<div class="section"> +<h3>RenderContextAttributes to the rescue<a name="RenderContextAttributes_to_the_rescue"></a></h3> + +<p> + Although a StrutsRenderContext can only be used once to communicate request parameters from the ActionRequest + to the next RenderRequest (stored in the ActionForm), the Struts Bridge provides another, completely + transparent, solution which can be used without any required changes to the Struts Application. + </p> + +<p> + The Struts Bridge can be configured, using a simple xml definition, to always save specific named request + attributes during an ActionRequest and restore these only during the next RenderRequest or optionally every + RenderRequest until the next ActionRequest or a RenderRequest for a different Struts Page URL is invoked. + </p> + +<p> + The request attribute values will be saved in the web session which requires them to implement the + <tt>Serializable</tt> interface. + </p> + +<p> + An example struts-portlet-config.xml (the name of this file is configurable) definition might look like: + </p> +<div class="source"> +<pre> + <?xml version="1.0" encoding="UTF-8"?> + <config> + <render-context> + <attribute name="errors"/> + <attribute name="message" keep="true"/> + <attribute prefix="com.foo.bar" keep="true"/> + </render-context> + </config></pre></div> + <i>(This (adapted) example is taken from the JPetstore Portlet example provided with the + <a class="externalLink" href="http://portals.apache.org/jetspeed-2" target="_nw">Jetspeed-2</a> Portal.)</i> + + +<p> + With the above example configuration, all request attributes named <i>errors</i> and <i>message</i> are + saved after the ActionRequest. The <i>errors</i> object is restored only once, the <i>message</i> object + will be restored until the next ActionRequest or when the Struts Page URL is changed. + </p> + +<p> + Furthermore, every request attribute which name start with <i>com.foo.bar</i> is also saved after the ActionRequest. + With the "prefix" attribute type definition, a whole range of attributes can be configured at once. + </p> + +<p> + Using the RenderContextAttributes configuration, a Struts Action can still forward (without redirecting) to a + JSP in a Portlet while passing its required data through the request attributes. Request scoped ActionForms + can also safely be used for this as the Struts Bridge will automatically remove them from the session again + when they go out of scope! + </p> + +<p> + Using the "single use only" configuration (meaning: without the keep="true" attribute) allows one to pass on rather large + objects to the RenderRequest because, even if they are stored in the Session, this will only be for a very + short period (milliseconds). Of course, with a subsequent RenderRequest these objects won't be available + anymore and the specific View Renderer must be able to handle that situation properly.<br /> + Error objects or error messages (other than ActionMessages and ActionErrors which are already automatically + saved in the StrutsRenderContext) are also reasonable candidates to use like this. + </p> + </div> + +<div class="section"> +<h3>Rendering valid Portlet urls with the Struts JSP Tags<a name="Rendering_valid_Portlet_urls_with_the_Struts_JSP_Tags"></a></h3> + +<p> + Another problem with using Struts for Portlet Development is rendering valid urls. + </p> + +<p> + There are actually two different type of problems: urls for resources likes images, Javascript or CSS + stylesheets which needs to be loaded by the client (browser), and urls for interacting with the Portlet + itself. + </p> + +<p> + The problem with resource urls is that the content of a Portlet is only included by the Portal, + together with possible content of other Portlets shown on the same page. Although the Portlet runs within + its own context (the same as the web application it is based on), the client (browser) sees only the context + of the Portal page it is currently pointed at. + </p> + +<p> + A Portlet therefore cannot make use of relative src locations for a resource url while this is perfectly valid + (and usually preferred) in a Web Application. For a client to be able to retrieve a resource, its url + really must include the full context path of the Web Application. + </p> + +<p> + For interacting with the Portlet special PortletURLs must be used which can only be generated using the + Portlet API or through the Portlet JSP Tags. The Struts JSP Tags only generate urls valid for a Web + Application and also doesn't provide some kind of URLProvider interface like JSF. + </p> + +<p> + Furthermore there are two different PortletURL types: ActionURLs and RenderURLs. + It is very important to generate the correct type of url for a certain interaction. Forms must *always* use + a POST to an ActionURL, but for generated links it will have to be determined which type of url actually + is needed. + </p> + +<p> + To solve these problems, the Struts Bridge provides enhanced versions of the Struts HTML JSP Tags (including + EL variants), which take the Portlet environment into account. Furthermore, using a separate element in + the struts-portlet-config.xml definition, specific url paths can be configured to be of a certain type + (Resource, ActionURL, RenderURL) only. + </p> + +<p> + For the enhanced Struts HTML JSP Tags (html:form, html:link, html:rewrite, html:image and html:img), four + different TLDs are provided: an EL and non-EL variant, and for both a full replacement of the Struts + supplied struts-html.tld as well as a separate struts-portlet.tld containing only the enhanced Tags definitions. + </p> + +<p> + The full replacement TLDs makes it very easy for migrating a Struts Application to a Portlet context: simply + map the new TLD in web.xml or redefine the taglib uri in the JSP using: + </p> +<div class="source"> +<pre> + <%@ taglib uri="http://portals.apache.org/bridges/struts/tags-portlet-html" prefix="html" %></pre></div> + or - - - - - - - - </div> - <div class="clear"> - <hr/> - </div> +<div class="source"> +<pre> + <%@ taglib uri="http://portals.apache.org/bridges/struts/tags-portlet-html-el" prefix="html-el" %></pre></div> + <i>(Note: the Struts Bridge library contains all the TLDs so you don't need to add them yourself + somewhere under WEB-INF/.)</i> + + +<p> + For the enhanced html:link and html:rewrite Tags, three additional boolean attributes are defined: actionURL, + renderURL and resourceURL. Using these attributes one can specify which type of url must be generated (only + value "true" is supported). + </p> + +<p> + If none of these attributes is specified (with value "true") these Tags will by default generate a RenderURL. + </p> + +<p> + But, the default can be changed (only between renderURL and actionURL) using a struts-portlet-config.xml + definition. Furthermore, for specific url path (prefixes) you can specify which type of url must be generated + (but with one of the three additional boolean url type attributes this can always be overriden). + </p> + +<p> + An example struts-portlet-config.xml with portlet url type definitions might look like: + </p> +<div class="source"> +<pre> + <?xml version="1.0" encoding="UTF-8"?> + <config> + <render-context> + <attribute name="errors"/> + <attribute name="message" keep="true"/> + </render-context> + <portlet-url-type> + <action path="/shop/add"/> + <action path="/shop/switch"/> + <action path="/shop/remove"/> + <action path="/shop/signoff"/> + <action path="/shop/viewCategory"/> + <action path="/shop/viewItem"/> + <action path="/shop/viewProduct"/> + <action path="/shop/viewCart"/> + <action path="/shop/newOrder"/> + <render path="/shop/newOrderForm"/> + <action path="/shop/listOrders"/> + <resource path="/images/"/> + </portlet-url-type> + </config></pre></div> + <i>(This is the full configuration used for the JPetstore Portlet example provided with the + <a class="externalLink" href="http://portals.apache.org/jetspeed-2" target="_nw">Jetspeed-2</a> Portal.)</i> + + +<p> + In the above example the portlet-url-type element contains three different sub elements: action, render and + resource. Their path attribute specifies the prefix to which specific urls are matched. This matching will be + done using best match. Internally, the paths will be ordered on longest definition first. + </p> + +<p> + Not shown in the above example is the optional default="render"|"action" attribute for the portlet-url-type + element. With it, the default type of portlet-url can be changed from "render" to "action" as is used in the + Struts Mailreader Demo Portlet (also provided by the <a class="externalLink" href="http://portals.apache.org/jetspeed-2" target="_nw">Jetspeed-2</a> + Portal): + </p> +<div class="source"> +<pre> + <?xml version="1.0" encoding="UTF-8"?> + <config> + <portlet-url-type default="action"/> + </config></pre></div> + This feature is especially useful for Struts Applications who were configured using an earlier version of + the Struts Bridge (0.1) which used an ActionURL as default, like the above Struts Mailreader Demo Portlet. + + +<p> + The enhanced html:img and html:image Tags, as well as the html:link and html:rewrite Tags, can be used to + generate resource urls using relative (not prefixed with a '/') src references. The Tags will then + automatically determine the correct url to generate using the current Struts Page URL as defined for this + RenderRequest. + </p> + +<p> + This allows one to replace hard coded resource urls like + </p> +<div class="source"> +<pre><img src="../images/struts-bridge.gif"/></pre></div> + with + +<div class="source"> +<pre><html:image src="../images/struts-bridge.gif"/></pre></div> + A simple change with no technical impact, but it will allow the same JSP to be used for both a Web Application + and a Portlet. The JPetstore Portlet example as provided by <a class="externalLink" href="http://portals.apache.org/jetspeed-2" target="_nw">Jetspeed-2</a> + makes full use of this feature. + + </div> + +<div class="section"> +<h3>PortletRequestProcessor and PortletTilesRequestProcessor<a name="PortletRequestProcessor_and_PortletTilesRequestProcessor"></a></h3> + +<p> + The Struts Bridge requires a different RequestProcessor to be used for the Struts Application: a <tt> + PortletRequestProcessor</tt>. If a Struts config doesn't define one, or defines one which isn't based on the + PortletRequestProcessor, it will be replaced automatically by the Struts Bridge. + </p> + +<p> + The Struts Bridge also supports Tiles to be used with the <tt>PortletTilesRequestProcessor</tt>. If the + TilesPlugin is defined (as required to be able to use Tiles in Struts) it will be recognized by the Struts + Bridge and then the PortletTilesRequestProcessor will be used instead (if not configured already). + </p> + +<p> + Tiles can be used without problem within a Portlet context, even for Action Mapping or ActionForward paths, + although the same considerations and restrictions must be taken into account as described above. + </p> + +<p> + 1.0.1: For proper handling of the Tiles Context, with version 1.0 the Tiles ComponentConstants.COMPONENT_CONTEXT had to be + set as RenderContextAttribute like this: + </p> +<div class="source"> +<pre> + <?xml version="1.0" encoding="UTF-8"?> + <config> + <render-context> + <attribute name="org.apache.struts.taglib.tiles.CompContext"/> + ... + </render-context> + ... + </config></pre></div> + With the 1.0.1 release, this isn't necessary anymore as the Struts Bridge will register this special attribute + itself automatically if it hasn't been defined in the struts-portlet-config.xml already. + + </div> + +<div class="section"> +<h3>Running your application as Portlet and Web Application at the same time<a name="Running_your_application_as_Portlet_and_Web_Application_at_the_same_time"></a></h3> + +<p> + Although the Struts Bridge is created to allow Struts Applications to run in a Portlet context, it also allows + the same application to be run in a Servlet context too. + </p> + +<p> + If the Struts Bridge PortletServlet (which extends ActionServlet) detects it is not accessed from a Portlet + context is simply delegates back to the underlying Struts Framework. + </p> + +<p> + Provided the Struts Application doesn't use any Portlet specific features and the Action Mapping configuration + is also (still) valid for a Web Application, the same application war can be deployed as Web application and + as Portlet Application. When deployed in a Portal, the application can even be accessed as Portlet or as + Web Application at the same time! + </p> + +<p> + The JPetstore Portlet example provided by <a class="externalLink" href="http://portals.apache.org/jetspeed-2" target="_nw">Jetspeed-2</a> is one + example of such a "dual" mode Struts Application. + </p> + +<p> + Another benefit of such a "dual" mode Struts Application is that it can be tested as Web Application + which <i>is</i> somewhat easier than testing it as a Portlet. + </p> + </div> + +<div class="section"> +<h3>1.0.1: Multiple StrutsPortlet instances PORTLET_SCOPE isolated StrutsServlet sessions<a name="a1.0.1:_Multiple_StrutsPortlet_instances_PORTLET_SCOPE_isolated_StrutsServlet_sessions"></a></h3> + +<p> + The Struts framework itself, as well as many Struts applications make have use of the (Servlet) Session for storing user state. + When you want to use multiple StrutsPortlets from the same web application this can cause conflicts and session state corruption. + With Struts Bridge release 1.0.1, this now has been solved by (optionally, and not by default) isolating the Session scope + seen by the StrutsServlet to PortletSession.PORTLET_SCOPE. + </p> + +<p> + If the optional StrutsPortlet init parameter <tt>PortletScopeStrutsSession</tt> is set to true, the Session object provided to the + StrutsServlet will be a Proxy for the PortletSession and will provide only access to the PortletSession.PORTLET_SCOPE attributes. + </p> + +<p> + One caveat though: If you also need to use direct Servlet access to the Struts application (meaning: the browser is invoking the + Servlet directly, not through the Portlet), this Servlet won't "see" the previously APPLICATION_SCOPE Session attributes anymore.<br /> + This can be an issue for features like binary file (pdf) rendering through a servlet which needs to use the Session to access its data. + To solve this, the utility + <a href="../portals-bridges-common/apidocs/org/apache/portals/bridges/util/PortletWindowUtils.html" target="_nw">PortletWindowUtils</a> class can + be used which provides methods to access a specific Portlet instance its PORTLET_SCOPE session attributes based on its PortletWindowId.<br /> + That PortletWindowId (which a Portlet can retrieve itself using the PortletWindowUtils) needs to be passed on to the Servlet first + (for example as query-string parameter on a link send to the browser) for it to be able to make use of it. + </p> + </div> </div> - </body> -</html> + + + </div> + </div> + <div class="clear"> + <hr/> + </div> + <div id="footer"> + <div class="xright"> + Copyright © 2004-2022 + <a href="http://www.apache.org/">Apache Software Foundation</a>. + All Rights Reserved. + + </div> + <div class="clear"> + <hr/> + </div> + </div> + </body> +</html>
