Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: How do you bind session attributes to object with webflow?

  1. #11
    Join Date
    Sep 2004
    Posts
    346

    Default Perhaps I see what you are trying to say....

    Parameters vs Attributes... So in addition I guess I need a mechanism to populate from attributes not just parameters so

    <property name="populateFrom" value="requestParam,request,session,flow"/>

    with the default being requestParam

  2. #12
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    When you say populate, you mean "bind" right. You want to bind input in some attribute source to a backing form object? You want to be able to take into account multiple attribute sources in a configurable order?

    I think I get it, but please, let's use our terminology or else confusion results.

    One issue here is there is no 'session' construct known to the web flow system: only request and flow. I'm not sure if it makes sense to add first-class support for session attributes, attempting to mask the location of the session store for different environments. We'll have to see about that.

    I agree with a "AttributeSourceChain" that will try to resolve a attribute in one or more ordered sources, like event/request/flow. Sounds useful - if we can get the spring data binder retrofitted to work with the attribute source interface, it shouldn't be a big deal.

    Keith
    Keith Donald
    Core Spring Development Team

  3. #13
    Join Date
    Sep 2004
    Posts
    346

    Default Yes that's it...

    Actuially it's fine not to have first-class support for session attributes. If I want to access a session attribute directly I can always put it into request scope or flow scope using the same method we described.

    I'll give the actual example of what I am trying to accomplish.

    in session there are 2 attributes (type:Integer and specialty:String)
    I want to encapsulate those attributes in a Profile object that then I can access typesafely from my action. so in this case I would have a backing form object containing type and specialty. Workflow FormAction would automatically bind to my backing form object from session and I can chose to have this object in either request or flow scope so in my action I can simply call

    Code:
    Profile profile = &#40;Profile&#41;context.getRequestScope&#40;&#41;.getAttribute&#40;"profile"&#41;;
    The only reason I would want to refer to my object in session scope is if the object is already there in which case your interface accomplishes this nicely. I don't like the interface method however because there could be different sources for the object (besides just session) and I didn't see how that would be addressed.

  4. #14
    Join Date
    Sep 2004
    Posts
    346

    Default Actually I like the interface..

    Basically what you are say in the implementation as to where the source is is up to me but in that case I should be able to inject the implementation for resolving each object


    i.e: action itself implements

    public Object getObject(String objectName, RequestContext context);

    public void setObjectRetreivalImplementation(Hashmap implementations);

    The implementation will look up in implementations hashmap and call method

    public Object getObject(String objectName, RequestContext context);

    which all implementations will have to implement.

    So basically I just inject in implementations and everything should work...

  5. #15
    Join Date
    Sep 2004
    Posts
    346

    Default I opened a JIRA for this:


  6. #16
    Join Date
    Sep 2004
    Posts
    346

    Default I'm thinking that FormAction is currently too limited.

    I'm thinking that FormAction is currently too limited. It only allows creation of one form object per action. My thought is that if using hibernate or another ORM tool what you want instead is multiple objects (one per each domain object) so that at the time you run the action the object graph will already be created and all you need to do is extract it from the context and use it to query or persist. This avoids the bulk of the work generally in actions to assemble domain objects.

    So basically this is IoC for a scope object to either create object in scope and set properties, set property on object already in specified scope or add object to collection of an object already in specified scope.

    Code:
    <bean id="phoneBookInjector" class="spring.ContextInjector">
        <property name="defaultAttributeSourceChain" value="parameter,request,flow,session,context"/>
        <property name="defaultPopulation" value="true"/>
        <property name="propertyAttributeResolvers">
           <map>
             <entry key="phoneNumber">
              <bean class="spring.PortletAttributeResolver">
                   <property name="from" value="PHONE_NUMBER"/> 
                   <property name="attributeSourceChain" 
                                  value="parameter,request,flow,session,context"/>
              </bean>
             </entry>
           </map>
        </property>
        <property name="formObjectName" value="phoneBook"/> 
        <property name="formObjectClass" value="app.domain.PhoneBook"/> 
        <property name="formObjectScopeAsString" value="request"/> 
        <property name="validator"> 
            <bean id="queryValidator" class="app.domain.PhoneBookValidator"/> 
        </property> 
    </bean>
    
    <bean id="phoneBookInjector">
        <property name="propertyResolver">
           <map>
             <entry key="phoneNumber">
               <bean class="spring.PropertyResolver">
                  <property name="to" value="street">
                  <property name="from" value="STREET"/> 
                 <property name="attributeSourceChain" 
                                 value="request"/>
               </bean>
             </entry>
           </map>
        </property>
        <property name="formObjectName" value="phoneBook.addresses"/> 
        <property name="formObjectClass" value="app.domain.PhoneBook"/> 
        <property name="formObjectScopeAsString" value="request"/> 
        <property name="validator"> 
            <bean id="queryValidator" class="app.domain.PhoneBookValidator"/> 
        </property> 
    </bean>
    
    <bean id="app.phone.SavePhone" 
       class="org.springframework.web.flow.action.SavePhoneInjectionAction"> 
       <property name="injectors">
            <list> 
                <ref bean="phoneBookInjector"/>
                <ref bean="phoneBookAddressInjector"/>
             </list>
       </proerty>
    </bean>

    Basically an explanation of the intended implementation is as follows.

    The functionality of InjectionAction class is as follows:
    1) In example action in flow SavePhone is implemented by SavePhoneInjectionAction which extends InjectionAction and probably extends FormAction (if FormAction is not deprecated)
    2) It reads list of injectors in order and proccess them


    The functionality of ContextInjector class is as follows:
    1) instantiate formObjectClass in scope if it does not already exist.
    2) for each property in class find a property resolver in following precedence
    • a) an explicit PropertyResolver in propertyResolvers
      b) a default PropertyResolver (which can be injected) if none specified and defaultPopulation is true

    3) for each property instantiate PropertyResolver and
    • a) inject defaultAttributeSourceChain if not already specified for the property resolver
      b) inject property name as "to"

    4) Once instantiated object has been populated, validate if necessary and then set formObjectName to point to object in the scope formObjectScopeAsString specified

    5) If formObjectName in the form "phoneBook.addresses" and addresses is a collection then find phoneBook in the scope specified by formObjectScopeAsString and invoke add method to insert newly populated object in collection.

    The functionality of PropertyResolver is as follows:
    1) For each scope specified in attributeSourceChain, search in that scope for "from" name or "to" name if "from" not specified.


    To retreive the object PhoneBook you would simply call:

    Code:
    PhoneBook phoneBook = &#40;PhoneBook&#41;context.getRequestScope&#40;&#41;.getAttribute&#40;"phoneBook"&#41;;
    and save it since it is already populated (both the properties and the associated addresses).

    I am looking for feedback in the following categories:
    1) Will this be as useful to you as it will be for me?
    2) Does anyone have any feedback on the intended implementation (including improvements)?
    3) Is anyone interested in implementing or helping with the intended implementation?

  7. #17
    Join Date
    Sep 2004
    Posts
    133

    Default

    Hi garpinc2 ,

    u have 2 <bean id="phoneBookInjector"/> in the your above code.
    If u need multi form objects , then multi validators are unavoidable , right ?

    moon

  8. #18
    Join Date
    Sep 2004
    Posts
    346

    Default No actually...

    No actually... you can have as many injectors as you'd like thus as many form beans as you'd like but each injector has one validator.. Am I missing something? app.phone.SavePhone is where multiple injectors are applied...

Similar Threads

  1. Replies: 2
    Last Post: Oct 10th, 2005, 05:12 PM
  2. OpenSessionInView + CMT Session usage
    By alesj in forum Data
    Replies: 7
    Last Post: Aug 16th, 2005, 02:32 AM
  3. Loosing my SecureContext
    By sklakken in forum Security
    Replies: 3
    Last Post: Jul 21st, 2005, 01:44 PM
  4. Replies: 0
    Last Post: Jan 6th, 2005, 08:19 AM
  5. Replies: 3
    Last Post: Nov 19th, 2004, 07:16 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •