Jeremy Ford wrote: > I'm also interested in the Struts Portlet idea. I've done some of my > own work porting the Struts dev branch to portlet based > implementation myself. The approach that I took was to that the > ActionServlet, convert to ActionPortlet, and follow the dependencies. > > How far along are you? What changes did you need to make to Struts? > My thought was to absorb any files that a portlet would need into a > J2/portlet specific version. This does have a side affect of any > changes made to Struts would need to copied into the portlet version. >
Well, I try to change as little within Struts as possible (with easy upgrade in mind). The framework I try to implement is as follows: StrutsPortlet Any Struts (local) url has to be specified as a Portlet url parameter. I'll still have to create adapted struts tags for that. Within the portlet processing (action AND render) I retrieve this url parameter to dispatch to an extended Struts ActionServlet also defined for the Portlet. To be able to access this PortletActionServlet I retrieve the current ServletContext and the servletrequest and response (this is portal specific: for Jetspeed I cast the PortletContext to JetspeedPortletContext to get it and PortletRequest and PortletResponse to servletrequest and servletresponse). I dispatch to the PortletActionServlet with the struts local url using my own request and response wrappers. The request wrapper ensures Struts can find the right paths and parameters and will use my own RequestDispatcher (more about that later). The response wrapper traps sendError and sendRedirect calls as well as encodeURL calls. In the PortletActionServlet I wrap the ServletContext and ServletConfig objects to trap getRequestDispatcher() calls during processAction. If a "nicely behaving" struts applications is done with action processing it normally continues with view rendering by forwarding or including. My RequestDispatcher will NOT perform any including or forwarding during processAction (not allowed) but instead creates an StrutsRenderContext object which contains the path to the resource to include and saves furthemore the current ActionConfig and optionally the ActionForm and ActionMessages if they were defined in request scope. This StrutsRenderContext is then temporarilly put into the request session. During the subsequent Portlet rendering (which will dispatch to the PortletActionServlet using the same path as during the processAction) I check in my extended RequestProcessor.process() first if I have a StrutsRenderContext in the session. If a StrutsRenderContext is found I put its ActionConfig and optionally ActionForm and ActionMessages in the request attributes and then simply dispatch to the saved path using including (but first I remove the StrutsRenderContext from the session). The restriction of this handling is that actions should not be chained with different ActionForms as only the first ActionForm will be populated with the (action)request parameters. Furthermore, all forwarding will be translated to including (portlet restriction). This part of the framework I have nearly finished. Other issues I have to handle are: Response.sendRedirect() My wrapped responses will trap any sendRedirect. If the redirect is performed during processAction I can handle it by modifiying the struts local url so subsequent portal rendering will retrieve the same struts page (only for struts local url's ofcourse otherwise a real redirect will be issued). The redirection path is saved in the StrutsRenderContext so that the next Portlet rendering will render the new path. If the redirect is issued during the rendering I probably will throw an exception or just ignore it (not sure what to do). Response.SendError() I like to allow sendError() still to be used (as is done a lot by the Struts core) by trapping it. If this is done during processAction I save the error and optional message in the StrutsRenderContext and during subsequent Portlet Rendering dispatch to a special error page (defined as special initalization parameter of the PortletActionServlet). That page then can render the error nicely formatted. If the error is send during Portlet rendering this error page is immediately dispatched to (including). Struts local url I need to adapt specific Struts tags as well as handle reponse.encodeURL() to render a Portlet url. Any url local to Struts will be saved as a special struts local uri request parameter. For any url targeted at an action mapping which has action handling (type attribute != null) an ActionRequestURL will be rendered. Otherwise a RenderRequestURL will be fine. I encode the struts local uri translating '?' and '&' currently in '$' otherwise uri query parameters would be seen a separate request parameters. This I decode before I dispatch to the Struts PortletActionServlet. I don't like this encoding but haven't found any other way around it. Thats about it. To sum it up: I only extend Struts ActionServlet and Struts RequestProcessor lightly and still have to extend a few Struts tags. Hope this gives an idea what I'm about to deliver (by next week I hope). Ate > > Jeremy Ford > [EMAIL PROTECTED] > > > -----Original Message----- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] > Sent: Friday, April 02, 2004 1:21 AM > To: Jetspeed Developers List > Subject: Re: [J2] Bug: render called twice after an actionRequest > > David Sean Taylor wrote: >> On Thursday, April 1, 2004, at 12:34 PM, <[EMAIL PROTECTED]> wrote: >> >>> I just noticed that a portlet render method is called twice as >>> result >>> of an >>> ActionRequest. >> >> That shouldn't happen. >> Im in the middle of refactoring and componentizing the navigation and >> URL code, so its very likely things will break. >> Im putting in unit tests around all the components >> Very much appreciate your help here, but please bear with me for a >> few days while I transition the code to a more manageable state >> and decouple the navigational state from Pluto's implementation. >> > > I know. I haven't much time left though for my Struts portlet > framework so I will delve into it > myself also. I will report back anything important I encounter if you > don't mind :-) > >> Have you tried debugging with Eclipse 3.0? It handles multithreading >> nicely. > > Well, yeah, I'm using Eclipse 3 now but I'm still getting used to it > as I come from IntelliJ > (painfully missing a few fine features now and then). > >> Or try changing the aggregator component's algorithm to single >> threaded to make debugging easier > > That's a good hint, didn't think of that. Is it configurable or do I > have to modify the code for it? > I'll check it out. > >>> This is partically troublesome as I'm currently trying to implement >>> Struts >>> as a Jetspeed portlet in which I perform Struts action processing >>> from processAction and Struts view rendering from doView. >>> >> This sounds very interesting. >> Will this be a general solution that you plan on contributing to J2? >> I think a Jetspeed/Struts portlet application framework is a valuable >> contribution. > > Sure, I'll contribute it to Jetspeed (I already promised so before). > > How much of a general solution it will be I don't know yet. There > will be some restrictions for Struts usage mainly because of portlet > restrictions in general. > Furthermore, I'm not trying to port existing standalone Struts > applications but to > provide a framework for new Struts porlet development based on the > current head > version of Struts (well, I'm currently using the non-released Struts > 1.2 version). > As test case though I'm using the Struts MessageReader example. > > I'm not sure yet though if I should submit it to Jetspeed as a whole > or partly also to Struts (if they are interested). > This will be part Jetspeed adaption and part Struts > modifications/extensions to allow Struts work within a Portlet > (mainly a specialized RequestProcessor, handling of URL's and delayed > view rendering). > >> >>> Hopefully someone has an idea? >>> >> Yes, Im pretty much dedicated to working on cleaning up this part of >> the code over the next week. > > Great. With a bit of luck I will be able to get a basic, first > version of the Struts Portlet framework for J2 up and running by then. > > Ate > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
