I was able to work on this yesterday, and the WebRequestServicerFilter approach has so far worked very well for me. For anyone interested, I have created a new Wiki page with all the source code. Hopefully this will be useful to others.
http://wiki.apache.org/tapestry/TokenizedRequestFilter Thanks, Shawn Quoting Shawn Church <[EMAIL PROTECTED]>: > Sam, > > Yes, I received Jeff's message late. I don't mind if it's a little > heavy, as long as it will work better than my current method. I will > certainly give it a try on Monday. I appreciate both of your > responses, > and I will post back my results as soon as possible. > > Thanks, > Shawn > > Sam Gendler wrote: > > Thanks Jeff. Shawn, I assume your email response to me crossed > paths > > with Jeff's, but if not, I'd look pretty carefully at his solution. > > It is a more heavyweight solution than I'm sure any of us want, but > it > > will definitely get the job done and doesn't look like it would be > too > > hard or time consuming to implement. > > > > I'll probably do it myself when I get a chance. If you like, I'll > > post my code here when I'm done, but I can't say when that will be. > > > > --sam > > > > On 10/20/06, Jeff Lubetkin <[EMAIL PROTECTED]> wrote: > >> Specifically, we use a service that implements > >> org.apache.tapestry.services.WebRequestServicerFilter. The only > method > >> you need to implement is WebRequestServicerFilter.service, and the > only > >> really important thing is to call servicer.service() to keep the > chain > >> going. See Tapestry's DisableCachingFilter for an example. > >> > >> To hook up a filter in hivemodule.xml, you just need to > instantiate the > >> service, then add it to the > >> "tapestry.request.WebRequestServicerPipeline" configuration point. > >> Example: > >> > >> <service-point id="SavedPostFilter" > >> interface="org.apache.tapestry.services.WebRequestFilter"> > >> <invoke-factory> > >> <construct class="com.foo.bar.SavedPostFilter"> > >> <!-- any service configuration here --> > >> </construct> > >> </invoke-factory> > >> </service-point> > >> > >> <contribution > >> configuration-id="tapestry.request.WebRequestServicerPipeline"> > >> <filter name="SavedPostFilter" > object="service:SavedPostFilter" > >> /> > >> </contribution> > >> > >> jeff > >> > >> -----Original Message----- > >> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of > Sam > >> Gendler > >> Sent: Friday, October 20, 2006 3:40 PM > >> To: Tapestry users > >> Subject: Re: RE: Recovery of session during pageValidate > >> > >> Can you expound upon how you plug in the WebRequestFilter. > >> Constructing the WebRequest subclass looks simple enough, and the > >> Callback factory dosn't seem too tough, but injecting a web > request > >> filter sounds like hivemind magic that I'm unaware of. > >> > >> This seems like something we'd want to provide a more accessible > >> solution for in the core tapestry framework. It is a fairly > common > >> requirement of webapps. Preserving the state of the current HTTP > >> request so that it can be restored in a callback later seems to me > like > >> something that we'd want to make very easy. > >> > >> --sam > >> > >> On 10/20/06, Jeff Lubetkin <[EMAIL PROTECTED]> wrote: > >> > Not sure if this will help, but here's how we handle this (it's > kinda > >> > complicated, but it works): > >> > > >> > * All of our callback generation for interstitial processes like > login > >> > >> > go through a Callback factory service. In order to preserve URL > >> > integrity for bookmarking and the like, we use an ICallback > >> > implementation that sends a redirect to the browser. > >> > * When a callback needs to be generated for a POST, or a GET > that is > >> > too long, the current request parameters (from > >> > HttpServletRequest.getParameterMap) are stored in session, along > with > >> > a randomly-generated token. The parameters are stripped from the > >> > request and the token is added as a the "postToken" parameter > >> > ("www.zillow.com/foo?postToken=123"). > >> > * We have a WebRequestFilter that handles "global" URL > parameters that > >> > >> > can appear on any request. This custom URL handling code sees > the > >> > "postToken" parameter and creates a wrapper WebRequest that > returns > >> > the saved parameters from the getParameterNames, > getParameterValue, > >> > and getParameterValues methods (passing the rest of the methods > >> > through to the wrapped WebRequest). This causes the request to > look > >> > just like it did before being sent off for authentication. > >> > Rewind/render happens just as expected. The only difference is > that > >> > (in the POST case) the method will be GET rather than POST in > the > >> > callback, but that rarely matters. > >> > > >> > The code for this is in no state to share, but hopefully the > idea > >> helps. > >> > > >> > jeff > >> > > >> > -----Original Message----- > >> > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf > Of Sam > >> > Gendler > >> > Sent: Friday, October 20, 2006 2:15 PM > >> > To: Tapestry users > >> > Subject: Re: Recovery of session during pageValidate > >> > > >> > I can think of a couple of ways of doing this. The way I do > this is > >> > to use an ExternalCallback, store that in session, and after > >> > successful authentication, I just execute the callback. > However, this > >> > >> > only works if you use ExternalLinks, and doesn't work at all if > >> > someone submits a form after being away from their computer for > long > >> > enough to lose their session. > >> > > >> > Here's what would be really useful, but doens't actually work, > >> > currently: > >> > > >> > If you have their serviceParameters, you shouldn't need to put > them > >> > back in a request via the URL of the age, I think. You should > just be > >> > >> > able to do something like this in your listener after they've > >> > successfully > >> > authenticated: > >> > > >> > @Persist > >> > public abstract IPage getPreviousPage(); public abstract void > >> > setPreviousPage(IPage page) > >> > > >> > @Persist > >> > public abstract Object[] getStoredServiceParameters(); public > abstract > >> > >> > void setStoredServiceParameters(Object[] params); > >> > > >> > public void doSomething(IRequestCycle cycle) { > >> > // check auth here > >> > > >> > if (authSuccess) { > >> > > cycle.setServiceParameters(getStoredServiceParameters()); > >> > cycle.activate(getPreviousPage()); > >> > return; > >> > } > >> > } > >> > > >> > Unfortunately, when a page is activated, it doesn't go through a > >> > rewind cycle, so even if the service parameters have all the > right > >> > info (and I'm not sure they do), the fields of your new page > would not > >> > >> > be populated with the data. > >> > > >> > I never found a solution to this, so my app has ExternalLinks > >> > everywhere I can get them, and if you submit a form hours after > you > >> > loaded it, you just have to suffer through the process of > filling it > >> > out again manually. It is more than a little frustrating, but > after > >> > fighting with this problem for a good long while, I gave up on > it. > >> > > >> > I'd love to find a way to force a page to go through the entire > >> > rewind/render cycle programmatically from a listener on another > page, > >> > but there doesn't seem to be a way to do this. > >> > > >> > --sam > >> > > >> > > --------------------------------------------------------------------- > >> > 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] > >> > >> > >> > --------------------------------------------------------------------- > >> 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] > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
