How do you bind session attributes to an object with webflow? FormAction automatically binds request attributes but how do you bind session attributes or for that matter attributes from any arbitrary scope?
How do you bind session attributes to an object with webflow? FormAction automatically binds request attributes but how do you bind session attributes or for that matter attributes from any arbitrary scope?
I think you are confusing the HttpServletRequest with the WebFlow RequestContext. WebFlow binds parameters from the HttpServletRequest, not attributes fromt the RequestContext.
I want to bind from HttpSession
FormAction takes event parameters and binds them to a backing object in a configurable scope (either request or flow.) In a servlet environment, the Event is a HttpServletRequestEvent, so the parameters are actually request parameters...
What are you trying to do again? Connect parameters in the request to a object in the session? In this case, I'd use a custom action to take the "context.getOriginatingEvent().getParameters() " and bind them to the session object, casting the Originating event to a HttpServletRequestEvent and accessing the HttpSession.
Keith Donald
Core Spring Development Team
rather than accessing the session object through request.getSession I want to inject the dependencies which exist in session into the backing object. i.e rather than service locator I want IoC.
UPDATED
Hmmm....well, that's kind of tricky as you need the request to pull the object out of the session to be thread safe.
My recommendation is to have a locator interface that decouples you from any specific object retrieval strategy:
This is actually a pretty good pattern, worth consideration adding as a suport class.Code:public HttpSessionObjectAccessor implements FlowObjectAccessor { public Object getObject(String objectName, RequestContext context) { HttpServletEvent event = (HttpServletEvent)context.getOriginatingEvent(); return event.getRequest().getSession().getAttribute(objectName); } } public interface FlowObjectAccessor { public Object getObject(String objectName, RequestContext context); }
Inject a configured instance into your action code, and then invoke it on each request to get the session object.
Keith
Keith Donald
Core Spring Development Team
How does that work when there are > 1 objects?
We'll need to change the interface to take a object name parameter...
Keith Donald
Core Spring Development Team
Doesn't seem to accomplish what I want... i.e: still service locator vs Ioc.
Let me see if I understand.
1) Web flow is like struts in that instance variables that are specific to request and likely to change from user to user are bad because the action classes are actually singletons not instantiated per request. right?
2) Here is the example in practical guide
This code caused PhoneBookQuery to be created in flow scope if it didn't already exist and it's attributes to be set from requests.Code:<bean id="person.Search.criteria.formAction" class="org.springframework.web.flow.action.FormAction"> <property name="formObjectName" value="query"/> <property name="formObjectClass" value="org.springframework.samples.phonebook.domain.PhoneBookQuery"/> <property name="formObjectScopeAsString" value="flow"/> <property name="validator"> <bean id="queryValidator" class="org.springframework.samples.phonebook.domain.PhoneBookQueryValidator"/> </property> </bean>
Now what I want is as follows.
Attributes exist in session which apply to an object that may or may not exists in the scope I want. Similar to above I want the object of the specified class to be created if it doesn't exist in the scope I want and it's values to be populated from the session rather than request. Better yet rather than it explicitly being populated from request as above I would like something like:
See <property name="populateFrom" value="request,session"/>Code:<bean id="person.Search.criteria.formAction" class="org.springframework.web.flow.action.FormAction"> <property name="populateFrom" value="request,session,flow"/> <property name="formObjectName" value="query"/> <property name="formObjectClass" value="org.springframework.samples.phonebook.domain.PhoneBookQuery"/> <property name="formObjectScopeAsString" value="flow"/> <property name="validator"> <bean id="queryValidator" class="org.springframework.samples.phonebook.domain.PhoneBookQueryValidator"/> </property> </bean>
That way it will try to populate from request first and then from session or in what ever order I specify with the first in the order taking precedent if it exists in both places.
Then
as in your example is sufficient to retreive the created object. I don't see the benefit of the interface that you described.Code:PhoneBookQuery query = (PhoneBookQuery)context.getFlowScope().getAttribute("query");
Well, the benefit of what I proposed is it fully decouples your actions from the HttpSession. That's it, really.
Yes, actions are singletons, as documented in the Action interface...
I''m having a hard time following you. I'll try and give a read again in a bit.
Keith Donald
Core Spring Development Team