You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Fernando Padilla <fe...@alum.mit.edu> on 2008/04/06 23:22:35 UTC

session-less forms

I have a requirement to not depend on HttpSession, but the Form 
component has a @Persist field that Tapestry wants to store in a 
session.  What are some options to avoid this?


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: session-less forms

Posted by Josh Canfield <jo...@gmail.com>.
> I have a requirement to not depend on HttpSession, but the Form  
> component has a @Persist field that Tapestry wants to store in a  
> session.  What are some options to avoid this?


I may have posted this before, but here it is again. I think it's a  
pretty good solution.

I created a session persistence strategy that only stores non-null  
values, and extended the Form to only store the validation if there  
are errors... The changes to the existing classes are minor.

Here's the code.

import org.apache.tapestry.ValidationTracker;
import org.apache.tapestry.ValidationTrackerImpl;
import org.apache.tapestry.annotations.Persist;

/**
  * Overrides the core {@link  
org.apache.tapestry.corelib.components.Form} in order to store the  
validation tracker only
  * when there is something to track.
  * <p/>
  * Created by IntelliJ IDEA.
  * User: joshcanfield
  * Date: Oct 26, 2007
  */
public class Form extends org.apache.tapestry.corelib.components.Form {
     @Persist("nonnull")
     private ValidationTracker _tracker;

     private ValidationTracker _nonPersistedTracker;

     public ValidationTracker getDefaultTracker() {
         if (_nonPersistedTracker == null) {
             if (_tracker != null) {
                 // _tracker is loaded via injection magic when it's  
in the session
                 _nonPersistedTracker = _tracker;
             } else {
                 _nonPersistedTracker = new ValidationTrackerImpl();
             }
         }
         return _nonPersistedTracker;
     }

     public void setDefaultTracker(ValidationTracker defaultTracker) {
         _nonPersistedTracker = defaultTracker;
     }

     protected void onAction() {
         if (_nonPersistedTracker.getHasErrors()) {
             _tracker = _nonPersistedTracker;
         } else {
             _tracker = null;
         }
     }

}


import org.apache.tapestry.internal.services.PersistentFieldChangeImpl;
import static  
org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
import org.apache.tapestry.services.PersistentFieldChange;
import org.apache.tapestry.services.PersistentFieldStrategy;
import org.apache.tapestry.services.Request;
import org.apache.tapestry.services.Session;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
  * Created by IntelliJ IDEA.
  * User: joshcanfield
  * Date: Oct 26, 2007
  */
public class NonNullSessionPersistentFieldStrategy implements  
PersistentFieldStrategy {
     /**
      * Prefix used to identify keys stored in the session.
      */
     static final String PREFIX = "nonnull:";

     private final Request _request;

     protected NonNullSessionPersistentFieldStrategy(Request request) {
         _request = request;
     }

     public final Collection<PersistentFieldChange>  
gatherFieldChanges(String pageName) {
         Session session = _request.getSession(false);

         if (session == null) return Collections.emptyList();

         List<PersistentFieldChange> result = newList();

         String fullPrefix = PREFIX + pageName + ":";

         for (String name : session.getAttributeNames(fullPrefix)) {
             PersistentFieldChange change = buildChange(name,  
session.getAttribute(name));

             result.add(change);
         }

         return result;
     }

     public void discardChanges(String pageName) {
         Session session = _request.getSession(false);

         if (session == null) return;

         String fullPrefix = PREFIX + pageName + ":";

         for (String name : session.getAttributeNames(fullPrefix)) {
             session.setAttribute(name, null);
         }
     }

     private PersistentFieldChange buildChange(String name, Object  
attribute) {
         // TODO: Regexp is probably too expensive for what we need  
here. Maybe an IOC InternalUtils
         // method for this purpose?

         String[] chunks = name.split(":");

         // Will be empty string for the root component
         String componentId = chunks[2];
         String fieldName = chunks[3];

         return new PersistentFieldChangeImpl(componentId, fieldName,  
attribute);
     }

     public final void postChange(String pageName, String componentId,  
String fieldName, Object newValue) {
         notBlank(pageName, "pageName");
         notBlank(fieldName, "fieldName");
         StringBuilder builder = new StringBuilder(PREFIX);
         builder.append(pageName);
         builder.append(':');

         if (componentId != null) builder.append(componentId);

         builder.append(':');
         builder.append(fieldName);
         // because we don't want to create a session when the object  
is null
         Session session = _request.getSession(newValue != null);
         if (session != null) {
             session.setAttribute(builder.toString(), newValue);
         }
     }

}

Add this to your app module:

     public void contributePersistentFieldManager(
             MappedConfiguration<String, PersistentFieldStrategy>  
configuration, Request request) {
         configuration.add("nonnull", new  
NonNullSessionPersistentFieldStrategy(request));
     }



On Apr 6, 2008, at 2:22 PM, Fernando Padilla wrote:

> I have a requirement to not depend on HttpSession, but the Form  
> component has a @Persist field that Tapestry wants to store in a  
> session.  What are some options to avoid this?
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: session-less forms

Posted by nicholas Krul <ni...@gmail.com>.
the @Meta("tapestry.persistence-strategy=X") works beautifully... no more
sessions till logged in.


On Mon, Apr 7, 2008 at 7:14 PM, Robert Zeigler <ro...@scazdl.org> wrote:

>
> On Apr 7, 2008, at 4/712:53 PM , Fernando Padilla wrote:
>
> > so.. the "client" strategy stores it in a cookie?
> >
> >
> Client strategy stores it in the url.
> Not sure how that would play out for myspace, etc.
>
> Robert
>
>
>
>  Yeah, I don't really have access to those either :)
> >
> > ps - This is for integration with GoogleGadgets/OpenSocial/MySpace/Hi5.
> >  So it's basically a portlet hosted on a different site.  And the requests
> > to my server are being proxied by MySpace/Hi5 so we don't have access to
> > cookies from the client side..
> >
> > pps - I am using Zones and Form/Zones, so I'm rendering on the same
> > request as the submit, and at first glance that seems to be working.  I just
> > wanted to make sure "persist"/"session" requirement wasn't going to bite me
> > later..
> >
> > ppps - So if we're doing the render on the same request as submit, we
> > don't really have to store the Validation object in the session right?
> >
> > Howard Lewis Ship wrote:
> >
> > > The approach I would take would be to configure the Form to store its
> > > persistent fields on the client, rather than in the Session.
> > > On your PAGE, you can add a @Meta annotation for this:
> > > @Meta("tapestry.persistence-strategy=client")
> > > public class MyPage { ...
> > > This sets the default persistence strategy for the entire page to be
> > > "client".  Since in most cases, @Persist is used without a specific
> > > strategy, even nested components (such as Form) will inherit a default
> > > persistent strategy from their container.
> > > I haven't tried this yet myself ... give it a try and report back!
> > > On Mon, Apr 7, 2008 at 5:05 AM, Peter Stavrinides
> > > <p....@albourne.com> wrote:
> > >
> > > > If I understand correctly you need to pass data completely
> > > > independent of
> > > > session state... then your options are hidden form fields, and or
> > > > URL
> > > > parameters. Of course then you would have to reinitialize your
> > > > properties
> > > > manually after posting, which is not such big a deal!
> > > >
> > > >
> > > >
> > > > Fernando Padilla wrote:
> > > >
> > > >  I have a requirement to not depend on HttpSession, but the Form
> > > > > component
> > > > >
> > > > has a @Persist field that Tapestry wants to store in a session.
> > > >  What are
> > > > some options to avoid this?
> > > >
> > > > >
> > > > >
> > > > > ---------------------------------------------------------------------
> > > > > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > > > > For additional commands, e-mail: users-help@tapestry.apache.org
> > > > >
> > > > >
> > > > > ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > > > For additional commands, e-mail: users-help@tapestry.apache.org
> > > >
> > > >
> > > >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: session-less forms

Posted by Robert Zeigler <ro...@scazdl.org>.
On Apr 7, 2008, at 4/712:53 PM , Fernando Padilla wrote:
> so.. the "client" strategy stores it in a cookie?
>

Client strategy stores it in the url.
Not sure how that would play out for myspace, etc.

Robert


> Yeah, I don't really have access to those either :)
>
> ps - This is for integration with GoogleGadgets/OpenSocial/MySpace/ 
> Hi5.  So it's basically a portlet hosted on a different site.  And  
> the requests to my server are being proxied by MySpace/Hi5 so we  
> don't have access to cookies from the client side..
>
> pps - I am using Zones and Form/Zones, so I'm rendering on the same  
> request as the submit, and at first glance that seems to be  
> working.  I just wanted to make sure "persist"/"session" requirement  
> wasn't going to bite me later..
>
> ppps - So if we're doing the render on the same request as submit,  
> we don't really have to store the Validation object in the session  
> right?
>
> Howard Lewis Ship wrote:
>> The approach I would take would be to configure the Form to store its
>> persistent fields on the client, rather than in the Session.
>> On your PAGE, you can add a @Meta annotation for this:
>> @Meta("tapestry.persistence-strategy=client")
>> public class MyPage { ...
>> This sets the default persistence strategy for the entire page to be
>> "client".  Since in most cases, @Persist is used without a specific
>> strategy, even nested components (such as Form) will inherit a  
>> default
>> persistent strategy from their container.
>> I haven't tried this yet myself ... give it a try and report back!
>> On Mon, Apr 7, 2008 at 5:05 AM, Peter Stavrinides
>> <p....@albourne.com> wrote:
>>> If I understand correctly you need to pass data completely  
>>> independent of
>>> session state... then your options are hidden form fields, and or  
>>> URL
>>> parameters. Of course then you would have to reinitialize your  
>>> properties
>>> manually after posting, which is not such big a deal!
>>>
>>>
>>>
>>> Fernando Padilla wrote:
>>>
>>>> I have a requirement to not depend on HttpSession, but the Form  
>>>> component
>>> has a @Persist field that Tapestry wants to store in a session.   
>>> What are
>>> some options to avoid this?
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: session-less forms

Posted by Fernando Padilla <fe...@alum.mit.edu>.
so.. the "client" strategy stores it in a cookie?

Yeah, I don't really have access to those either :)

ps - This is for integration with GoogleGadgets/OpenSocial/MySpace/Hi5. 
  So it's basically a portlet hosted on a different site.  And the 
requests to my server are being proxied by MySpace/Hi5 so we don't have 
access to cookies from the client side..

pps - I am using Zones and Form/Zones, so I'm rendering on the same 
request as the submit, and at first glance that seems to be working.  I 
just wanted to make sure "persist"/"session" requirement wasn't going to 
bite me later..

ppps - So if we're doing the render on the same request as submit, we 
don't really have to store the Validation object in the session right?

Howard Lewis Ship wrote:
> The approach I would take would be to configure the Form to store its
> persistent fields on the client, rather than in the Session.
> 
> On your PAGE, you can add a @Meta annotation for this:
> 
> @Meta("tapestry.persistence-strategy=client")
> public class MyPage { ...
> 
> This sets the default persistence strategy for the entire page to be
> "client".  Since in most cases, @Persist is used without a specific
> strategy, even nested components (such as Form) will inherit a default
> persistent strategy from their container.
> 
> I haven't tried this yet myself ... give it a try and report back!
> 
> On Mon, Apr 7, 2008 at 5:05 AM, Peter Stavrinides
> <p....@albourne.com> wrote:
>> If I understand correctly you need to pass data completely independent of
>> session state... then your options are hidden form fields, and or URL
>> parameters. Of course then you would have to reinitialize your properties
>> manually after posting, which is not such big a deal!
>>
>>
>>
>>  Fernando Padilla wrote:
>>
>>> I have a requirement to not depend on HttpSession, but the Form component
>> has a @Persist field that Tapestry wants to store in a session.  What are
>> some options to avoid this?
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>  ---------------------------------------------------------------------
>>  To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>  For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
> 
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: session-less forms

Posted by Howard Lewis Ship <hl...@gmail.com>.
The approach I would take would be to configure the Form to store its
persistent fields on the client, rather than in the Session.

On your PAGE, you can add a @Meta annotation for this:

@Meta("tapestry.persistence-strategy=client")
public class MyPage { ...

This sets the default persistence strategy for the entire page to be
"client".  Since in most cases, @Persist is used without a specific
strategy, even nested components (such as Form) will inherit a default
persistent strategy from their container.

I haven't tried this yet myself ... give it a try and report back!

On Mon, Apr 7, 2008 at 5:05 AM, Peter Stavrinides
<p....@albourne.com> wrote:
> If I understand correctly you need to pass data completely independent of
> session state... then your options are hidden form fields, and or URL
> parameters. Of course then you would have to reinitialize your properties
> manually after posting, which is not such big a deal!
>
>
>
>  Fernando Padilla wrote:
>
> > I have a requirement to not depend on HttpSession, but the Form component
> has a @Persist field that Tapestry wants to store in a session.  What are
> some options to avoid this?
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>  For additional commands, e-mail: users-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: session-less forms

Posted by Peter Stavrinides <p....@albourne.com>.
If I understand correctly you need to pass data completely independent 
of session state... then your options are hidden form fields, and or URL 
parameters. Of course then you would have to reinitialize your 
properties manually after posting, which is not such big a deal!

Fernando Padilla wrote:
> I have a requirement to not depend on HttpSession, but the Form 
> component has a @Persist field that Tapestry wants to store in a 
> session.  What are some options to avoid this?
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org