See comments below
Xavier Lawrence wrote:
Hi all,
I would appreciate any help on the following problem. It is holding me for now several days, and I am getting completely lost.
I have a struts portlet which uses a filter. The SvcIFilter call has to be the first on the way in and the last on the way out. It is used to open/close Connections to a database.
* We assume that any SvcI object must remain open until after the jsp * has done its stuff, i.e. after the action returns but before we finally * deliver the response. This filter allows us to implant a callback object * which has a close method which will be called when the request returns.
I also have a second filter, which is a badic XSLT filter.
The stand-alone struts application works fine, with the following configuration:
<filter-mapping> <filter-name>SvcI Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter-mapping> <filter-name>XSLT Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
For the Portlet, I started getting into troubles because the close method of the SvcI filter was called more than once. That is, we have a strict open-close sequence which works fine in the stand alone application. Basically, open opens connection and close commits transactions and closes connections. I first tried to configure the web.xml file like this:
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> . . . <filter-mapping> <filter-name>SvcI Filter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
<filter-mapping> <filter-name>XSLT Filter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
Then I tried this: (change in the url-patttern)
<filter-mapping> <filter-name>SvcI Filter</filter-name> <url-pattern>*.do</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
<filter-mapping> <filter-name>XSLT Filter</filter-name> <url-pattern>*.do</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
The last configuration gave better results (I could get up to the initial display of the portlet), but any click on a link (invoking a struts action) gave Exceptions because the close method of the filter was executed more than once. I also noticed that everything relied on the INCLUDE method of the dispatcher, (REQUEST and FORWARD don't seem to have any effect). If I don't put INCLUDE the filter is not called on the way out. So I have a situation where with some config the filter is called too often and the other not often enough :(
Jetspeed-2 delegates the processing of PortletRequests to portlets using the RequestDispatcher include method only.
Once you enter your Struts Portlet application the Struts Bridge (0.1 or 0.2) will process the request mapped by dispatching to the Struts PortletServlet. Your SvcI Filter will thus be activated at least two times already if you map it to /*.
Now, Struts action processing normally results in a forward or include of a JSP for rendering. This means, the RequestDispatcher include will be called again. In your initial filter-mapping (on /*) this would trigger the filter once more with your dispatcher methods mapping (this will probably lead to similar problems in your non-portlet application I think). Your second attempt using the /*.do url-pattern thus is much better as the the initial dispatch from the Portal to your Portlet Application and the dispatch from Struts to the jsp won't trigger your filter anymore.
The problems you are now still experiencing are most likely the result of an incorrect struts-config definition within a Portlet context. When you have an action mapping which forwards to another action mapping (called action chaining) you should take the following design issues in mind: - if the initial action mapping is targeted from an Action PortletURL using sp:form or the default from an sp:link or sp:rewrite tag in Struts Bridge 0.1, (see http://nagoya.apache.org/eyebrowse/[EMAIL PROTECTED]&msgId=2087322 for an explanation how this has changed in Struts Bridge 0.2) *AND* your forward isn't defined as redirect="true", the Struts Bridge will hold on to the original action mapping to be executed *again* during the following RenderRequest! This means that during the following RenderRequest a dispatch will follow to the original action url, as well as a dispatch to the forward action url (which will be automatically be transformed to an include by the Bridge), resulting in (at least) two times triggering of your filter. - if the initial action mapping is targeted from an Render PortletURL (using renderURL="true" on sp:link or sp:rewrite in Struts Bridge 0.1) the *same* thing will occurs during RenderRequest processing and even redirect="true" won't help you here (and you should have the same problem with your non-portlet version of the application if you have <dispatcher>INCLUDE</dispatcher> in the filter mapping).
Solutions: - in case your original action is targeted from an Action PorletURL use redirect="true" in your forward definition - in case of chained render actions just don't do it: try to consolidate the actions into one and forward (type include) to the jsp from that. - in case above isn't feasible or correct, you could maintain a invocation counter as request attribute in your filter and only do your initialization on first invocation and only cleanup when it goes down to zero again.
I hope this will get you going.
A strange thing was that when I tried to launch the portlet, Jetspeed started to print out these lines, just after the XSLT filter was called:
cheater: target value = 99 cheater: target value = 59 cheater: target value = 55 cheater: target value = 29
So what is going on ? It seems that the filter reloads the Number Guess portlet ??? Why would it do so ?
Totally unrelated.
The Number Guess porlet is on the start page of Jetspeed-2 and writes out a few debug messages to the console. You can ignore these. I guess you have your Portlet Application also defined on the start page and that is why you see the XSLT Filter being called as result of the same (Portal) request (if its before or after the Number Guess Portlet depends on the order the Poral Aggregator invokes the portlets).
How should I configure the url-pattern so the SVCI filter gets called the firston the way in and the last on the way out ??? I repeat, the stand-alone struts application works fine, and I am a bit lost at the moment.
Note that I am using the struts-bridge 0.1.
I advise to upgrade to the latest version in cvs. It gives you much easier control over Action/Render PorletURL creation as well as many new enhancements like Struts-EL support, transparent taglib usage and the ability to deploy your application.war as web application and/or as portlet application at the same time (see above link for further information).
Thanks in advance for any help.
Regards
Xavier
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
