Showing posts with label spring web flow. Show all posts
Showing posts with label spring web flow. Show all posts

Saturday, 17 May 2008

The advantage of Grails

This week Spring Source have released, Spring Web Flow 2, I've read release notes and this make me think about the advantage of Grails.

Let's see release notes:
DSL to define flows the fact is XML+EL. I think is much readable Grails DSL to define WebFlows and less verbose.
  • Spring Javascript is a JavaScript abstraction framework that allows you to progressively enhance a web page with behavior.
Spring Javascript is built over Dojo to provide Ajax abstractions and rich widget behavior, and Grails do it, with tags, and Ajax agnostic calls (Prototype, Dojo, YUI, etc).
  • The Spring Faces module contains Spring's support for JavaServerFaces.
Who cares JSF? The EJBs in the view layer, jeje.
  • Using Spring Security to secure your flows in a declarative manner
A lot of security plugins for Grails.
  • Using Tiles for JSP page composition and Ajax partial-rendering
Grails layouts, templates and content negotiation are fantastic to do this.

And the best, Grails can be updated to use Spring Webflow 2.

But, the advantage goes further, with Servlet 3.0 and generation of web.xml, I can do it with Grails plugins, and really futher with Java 7 and closures.

Sunday, 16 September 2007

Tip: Put result in session in Spring Web Flow

So, another tip with Spring Web Flow. Sometimes it's necessary put a result of bean-action in scope session, but in SWF 1.X doesn't have this feature, but you can make a simple action to do the work.

First, the flow definition:

<action-state id="saveProject">
<bean-action bean="projectManager" method="save">
<method-arguments>
<argument expression="flowScope.project" />
</method-arguments>
<method-result name="project" scope="request"/>
</bean-action>
<transition on="success" to="putInSession" />
</action-state>

<action-state id="putInSession">
<action bean="putInSessionAction">
<attribute name="sessionKey" value="project" />
</action>
<transition on="success" to="finish"/>
</action-state>


I call a bean-action "saveProject" and I put the result in request with key "project". Next, I execute the action "putInSession" and I set the attribute "sessionKey" with the value of the key "project", this mean thay the object to save in session is in the request with this key.

With this convention, here the Action implementation:

public class PutInSessionAction implements Action{

public Event execute(RequestContext context) throws Exception {

String key = (String) context.getAttributes().get("sessionKey");
Object value = context.getRequestScope().get(key);
context.getExternalContext().getSessionMap().put(key, value);

return new Event(this, "success");
}

}


This simple Action gets the object from the request and puts in session.

Sunday, 2 September 2007

Tip: Output a success message in a subflow in Spring Web Flow

In Ajax applications is common output a success or error message (like Google Mail interface). With Spring Web Flow I can define subflows to do commons things and reuse parts of the application but if I want to output a success message, the natural way it's to define a view state.

This tip shows other way to output a message.

I have a subflow to add a new company.

<start-state idref="enterCompanyData"/>

<view-state id="enterCompanyData" view="people/ajax/company_add">
<render-actions>
<action bean="formAction" method="setupForm" />
</render-actions>
<transition on="submit" to="saveCompany">
<action bean="formAction" method="bindAndValidate" />
</transition>
</view-state>

<action-state id="saveCompany">
<bean-action bean="companyManager" method="save">
<method-arguments>
<argument expression="flowScope.company" />
</method-arguments>
</bean-action>
<transition on="success" to="finish">
<set attribute="message" value="'company.addCompany.success'" />
</transition>
</action-state>

<end-state id="finish">
<output-mapper>
<mapping source="requestScope.message" target="message" />
</output-mapper>
</end-state>


When I save a company in the action state "saveCompany", I set an atttibute named "message" with a value of String 'company.addCompany.success' (with a single quotes, otherwise the expression language thinks that is a Java Bean), this value is a key for i18n.

In the end state "finish", I have to map the attribute message to the output.

Next, in the root flow, I have to capture the message and put in the flash scope.

<subflow-state id="companyAdd" flow="company-add-flow"> 
<attribute-mapper>
<output-mapper>
<mapping source="message" target="flashScope.message"/>
</output-mapper>
</attribute-mapper>
<transition on="finish" to="companyList" />
</subflow-state>


Putting the message in the flash scope, allow to view the message until next event.

And the last step is show the message in JSP, you have to include this code, in all view states.

<c:if test="${not empty message}">
<fmt:message key="${message}"/>
</c:if>