Chariot Training Classes

Training Courses

I run Chariot's training and mentoring services. We provide training in AngularJS, HTML5, Spring, Hibernate, Maven, Scala, and more.

Chariot Education Services

Technology

Chariot Emerging Tech

Learn about upcoming technologies and trends from my colleagues at Chariot Solutions.

Resources

Chariot Conferences

Podcasts

Entries in chariot-news (45)

Thursday
Nov112010

Upcoming Training Courses at Chariot Solutions

Folks, we have a few courses coming up in December I wanted to make you aware of:

  • December 7 − 10 : Enterprise Integration with Spring - this course focuses on back-end integration services, such as JMS, email, Spring Integration, web services (REST and Soap) and more.
  • December 14 − 17: Rich Web Applications with Spring - we discuss all of Spring's web-related technologies, from Spring MVC to WebFlow, to client-side validation with Spring JavaScript, as well as testing methods.
  • January 11-13: Hibernate with Spring - covers persistence strategies using Hibernate, a wildly popular but frequently mis-understood framework.  Annotations using JPA will be highlighted.

For more information, and to see Chariot's education calendar, visit our training web site.

Disclaimer:  I am the Director of Education Services at Chariot Solutions, and I approve this message :)

 

Thursday
Nov112010

November Philly Grails UG Meeting Recap - Ken Kousen

Tonight, at our Grails Meetup, we had the opportunity to hear Ken Kousen talking about Groovy and Web Services.  

Ken demonstrated using Groovy closures and methods, along with the Jax-WS services built in to Java 6, to tie in to web services.  

Ken demonstrated how to execute calls to web service stubs via Groovy in a more, well, Groovy way.  He wrote tests using Spock, which is a behavior driven testing tool, and also used the XmlSlurper to fetch data in XML format from a web service.  He showed use of the @Delegate Groovy annotation, and had a lot of nice collect & join methods for assembling web service URL parameters.

Ken also showed a bit on using GeoLocations in Groovy as well.

All in all, a useful presentation to reboot our Grails user group.  I'm glad he was able to take the time this week to prep and deliver the session.  We should have his slides on the Groovy Meetup site, as well as at ChariotSolutions.com, soon.

You can find out more about Ken Kousen (that's pronounced Cousin) - at KosenIT Inc.

Wednesday
Nov102010

Chariot Mobile Developer Series - Session 1 Recap

Today I attended the first event of Chariot's Mobile Development Series, held at the Conshohocken Marriott just outside Philadelphia. The topics of discussion were good starting ones - the current "state of the art" in mobile web technologies, delivered by Don Coleman, and a talk on mobile design decisions by Kevin Griffin.

One of the most common debates we hear today about mobile development is the decision to develop for a particular platform or to go "native." In the first talk, Don Coleman outlined that there are no "silver bullets" or magic frameworks, and that you can use both mobile web applications and native applications - the former to provide access to your site, the latter to give your applications sizzle and native features. Consider Amazon's online store - you can shop via a mobile HTML site, or you can use one of their native iPhone or Android applications.

Don discusses enterprise support

Don discussed some of the more interesting mobile scripting platforms, including the jQuery-based frameworks jqTouch and jQuery mobile, which is just emerging. He also mentioned Sencha Touch, which is commercial but he said the licensing was reasonable, and that it has lineage from GWT; it performs well according to his tests. He also mentioned that while it claims native widget look and feel, it's not a completely native experience.
One interesting topic brought up in the Q&A was the concept of a "universal platform" or standard for mobile development. He brought up was the Adobe Air 2.5 - they are making a play for a common mobile application platform, and although it sounds good, Don wants to see details.

Next up was Kevin Griffin - with a load of practical design advice for application developers. He has worked on mobile applications, including iOS, so brought a fair number of suggestions around developing first for the mobile device, rather than slimming down functionality of a traditional desktop or web application, and then attempting to cram them in buttons on the main interface.

Kevin used real iPhone applications as examples - the simplicity of the Twitter app - with the swiping to reveal more advanced options such as re-tweeting, the drop-down tweet box for adding pictures and the like, and the pulling up to scroll.  He also discussed how native applications can actually expand the hit targets for buttons natively - so that you can click somewhere nearby an icon and still trigger it.  He said this comes for free with native apps, but the HTML-based applications generally have to have custom HTML to achieve the same results.  

He reminded us that if you really want full features from a handset, the best way to do it today is to write it natively.  Accessing the camera, GPS, accelerometer, compass, those things are done best and most directly in a native application.  Not that you can't do something with HTML 5, but you'll get better, more consistent applications using the native platforms.

Kevin had five major "things to do":

  • User Experience - start with mobile first, or make sure you aren't trying to replicate an entire desktop application.  It's all about wanting to pick it up, hold it, interacting with it, so think simple.
  • Be ruthless with features - he showed us a flight simulator control panel, and then two buttons - fly and land.  Which one is a mobile user more likely to click (pilots, don't answer this one!)
  • Cognitive Effort - Don't make it a chore to use your application. There are probably 1/2 dozen others like yours out there, so make it simple and easy and fun.
  • Disappear - get things out of the way that you don't need.  Make them go away.
  • Input - types of input don't just include the keyboard - use the accelerometer ala Instapaper tilt scrolling, the camera as the Amazon application does, the GPS, audio etc…  

Kevin brought up two books that will end up on my reading list...  Tapworthy, by Josh Clark, and Mobile Design and Development by Brian Fling.

Both Don and Kevin provided their presentations online: Mobile Application Development and Mobile Design Concepts.

 

Sunday
Oct032010

Webflow + Roo Again - a More Complex Example...

Anyone want more info on Roo and Webflow?

Sure, you all do...

Before I start, I have to tell a quick story. I wrote this example because I didn't see good samples for the newer convention-driven webflow service call syntax. I also wanted to see what the bare-bones webflow JSPX pages would look like with the new tags.

I also needed a good example for chapter 6 of Roo in Action, which covers WebFlow, GWT and Flex. To make sure I was getting everything right, I put together this work in progress.

After I got done, I did a Google search to see whether or not anybody else had done samples like mine, which is a simple (not complete) shopping cart. It turns out that Willie Wheeler wrote a very good shopping cart example back in 2008. I encourage you to read up on that one, which is much more comprehensive than mine.

However, this is a Roo + WebFlow example, so I think the example is still quite valid.

The Example - a Shopping Cart

Yeah, yeah, yeah, shopping carts. Everybody has them, and mine is more lame! But since I'm more concerned with WebFlow mechanics than use-case perfection, let's just accept that mine is a very rudimentary example.

We're just going to hard-code three products, and allow users to add a quantity of each to a fictional cart. We will also allow users to remove the elements from the cart as well. Later phases of the webflow remain uncoded; this is just a getting started guide for now.

Installing WebFlow with Roo

This is the easiest part - just open the Roo shell on an existing project, and type

web flow

This will install all support for Web Flow, and drop a sample flow in the WEB-INF/views/sampleflow directory. You can check that out to get a feel for the mechanics, but here are the basics:

  • Web Flows are XML-driven state machines. Each user interacts with a web flow in a miniature session, called the Flow Context.
  • Flows are comprised of states and transitions.
  • Flows can store information between requests in various scopes, including the Flow Scope, which exists until the user exits the flow by hitting an end state.
  • Web Flows can execute business logic within a number of places
  • Any Spring Bean in the Application Context is available by id
  • If you build a Spring Bean that extends the WebFlow MultiAction class, and name your methods in a specific way, you can refer to them without passing a full signature.
  • To trigger a transition, you submit back to the web flow, passing it a special form variable (as shown in the examples below) with the name of the transition.

The Shopping Cart flow

We start with the flow definition preamble:

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

  <persistence-context />

We are using the persistence-context tag to enable JPA persistence tracking. Our JPA object, ShoppingCart, is held in this persistence context, and is our form object in the various views. You should note that if you want to use entities in your context, you should make them serializable.

Now, we start the flow. The first stage:

<var name="shoppingCart" class="com.chotchkies.model.ShoppingCart" />

<!-- A sample view state -->
<view-state id="show-cart">
  <transition on="add" to="show-products"/>
  <transition on="checkout" to="end-state"/>
  <transition on="removeItem" to="remove-item">
    <set name="flowScope.productId" value="requestParameters.productId" 
       type="java.lang.Long" />
  </transition>
  <transition on="empty">
    <evaluate expression="cartManager.clearCart" />
  </transition>
</view-state>

The first thing the flow does is pre-create our root JPA entity, ShoppingCart. This is stored within a special holder called the flow scope. Since it is a JPA entity, it is automatically flushed and persisted on each transition.

We then render our first view-state, show-cart. WebFlow tries to resolve the view name by looking up the definition in the Tiles view.xml file, located in the flow directory. I've replaced a more complex file with wildcard support, which was recently added in the newest Tiles release:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
    <definition extends="default" name="*">
        <put-attribute name="body" value="/WEB-INF/views/cart/{1}.jspx"/>
    </definition>
</tiles-definitions>

Note - this makes it possible to just drop new files in the flow definition directory, WEB-INF/views/cart, without modifying the views.xml file each time.

looks for a file named show-cart.jspx, within

We have several transitions, or exit paths, from this view-state:

  • add - transition to the show-products view-state
  • checkout - transition to the end-state
  • removeItem - transition to the remove-item state, but first pull the submitted productId and store it in the flowScope as productId
  • empty - a transition without a destination - this executes a method in the object named cartManager called clearCart - which removes the products from the user's shopping cart.

How do we execute these transitions? Here is a snippet from the button bar at the bottom of the cart page:

<form:form>
  <input type="submit" id="add" name="_eventId_add" value="Add Additional Items..." />
  <input type="submit" id="checkout" name="_eventId_checkout" value="Checkout" />
  <input type="submit" id="empty" name="_eventId_empty" value="Empty Cart" />
</form:form>

You can see the special names - they reference the transition name after the prefix _eventId and an additional underscore. When Web Flow sees these tags, it attempts to perform the transition attached to that tag.

More About Expressions and Convention

When navigating to the show-products state, an on-entry event is triggered, which fires off a call to a Spring Bean, CartManager. Here is the fragment:

<on-entry>
  <evaluate expression="cartManager.getAllProductsNotInCart" />
</on-entry>

The CartManagerImpl class, which extends the WebFlow MultiAction base class, has this method signature for getAllProductsNotInCart:

public Event getAllProductsNotInCart(RequestContext context)

Because it uses this syntax, we don't need to reference the parameters in the XML definition. Nice touch, eh? This pushes some of the details into the bean itself, but also can simplify the XML definition. Here is the full method:

@Override
public Event getAllProductsNotInCart(RequestContext context) {
  ShoppingCart cart = getCart(context);
  Set<Long> keySet = cart.getItems().keySet();
  List<Product> products = Product.findProductsNotIn(keySet);
  context.getViewScope().asMap().put("productList", products);
  return success();
}

private ShoppingCart getCart(RequestContext context) {
  ShoppingCart cart = (ShoppingCart) context.getFlowScope().get("shoppingCart");
  return cart;
}

This shows a few helpful conventions. First, the RequestContext is a class that provides access to all of the scopes, including flowScope and viewScope. In this case, because each time we show the products we want to re-evaluate whether they are in the cart, we place the information in the viewScope variable. This data is only held while rendering the view.

Our helper method, getCart, shows how to access the flow scope. Remember the shoppingCart variable defined in the var tag at the top of the flow? Yep, it's accessed using the context.getFlowScope() method.

Wrap-up - the full flow example

Those are some of the key conventions used by Web Flow. I'm working on this sample, which I'll be adding to a GIT repository soon. For now, here is the rest of the flow, and a complete sample page.

Cart Flow

Notice the end-state - it has a special attribute, commit=true. This makes sure that on exit of the end state, any in-flight JPA changes will be flushed and committed. This is the normal behavior on each step, but when leaving a flow in error, you may wish to have an error end state that does not commit.

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

  <persistence-context />

  <var name="shoppingCart" class="com.chotchkies.model.ShoppingCart" />

    <!-- A sample view state -->
    <view-state id="show-cart">
      <transition on="add" to="show-products"/>
      <transition on="checkout" to="end-state"/>
      <transition on="removeItem" to="remove-item">
        <set name="flowScope.productId" value="requestParameters.productId" 
           type="java.lang.Long" />
      </transition>
      <transition on="empty">
        <evaluate expression="cartManager.clearCart" />
      </transition>
    </view-state>

    <action-state id="remove-item">     
      <evaluate expression="cartManager.removeItemFromCart" />
      <transition on="success" to="show-cart" />
    </action-state>

    <view-state id="show-products">
      <on-entry>
        <evaluate expression="cartManager.getAllProductsNotInCart" />
      </on-entry>
      <transition on="select" to="confirm-product">               
        <evaluate expression="cartManager.configureCartItem" />
      </transition>
      <transition on="cancel" to="show-cart" />
    </view-state>

    <view-state id="confirm-product" model="flowScope.currentItem">           
      <transition on="confirm" to="show-cart"/>             
      <transition on="cancel" to="show-cart">
        <evaluate expression="cartManager.removeItemFromCart" />
      </transition>
    </view-state>

  <action-state id="add-product">
    <!-- KJR - todo -->
    <transition to="show-cart"/>
  </action-state>

  <view-state id="enter-address">
    <transition on="continue" to="confirm-shipping"/>
    <transition on="back" to="checkout-cart"/>
  </view-state>

  <view-state id="confirm-shipping">
    <transition on="continue" to="end-state"/>
    <transition on="back" to="enter-address"/>
  </view-state>

  <end-state id="end-state" view="end-state" commit="true"/>

</flow>

The show-products.jspx view

Note the use of the special variable, ${flowExecutionKey}, which represents the proper webflow flow for the server. If you're writing your own links, and not posting the form, you need to include this. Also note that all scoped variables are 'just there' in the context by their names.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page" 
  xmlns:page="urn:jsptagdir:/WEB-INF/tags/form" 
  xmlns:table="urn:jsptagdir:/WEB-INF/tags/form/fields" 
  xmlns:c="http://java.sun.com/jsp/jstl/core" 
  xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
  xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" 
  xmlns:form="http://www.springframework.org/tags/form" 
  version="2.0">
    <jsp:output omit-xml-declaration="yes"/>
    <h3>Shopping Cart Contents</h3>

    <ul>
      <c:forEach items="${productList}" var="product">
        <li>${product.name} - Price: ${product.price} -
         <c:url var="addUrl" value="">
          <c:param name="productId" value="${product.id}"/>
          <c:param name="_eventId" value="select"/>
          <c:param name="execution" value="${flowExecutionKey}" />
        </c:url>
          <a href="${addUrl}">Add...</a>
        </li>      
      </c:forEach>
    </ul> 

    <form:form>
      <input type="submit" id="cancel" name="_eventId_cancel" value="Cancel and return to cart..." />
    </form:form>

</div>
Sunday
Sep192010

Spring Roo and Web Flow, the Expergated Version...

I've had a number of people ask me recently about how Spring Roo works with Web Flow. Yes, there's the installation command, but what do you do from there? I've been penning a segment of Roo in Action to address this, but because it will take several months to get it through to the MEAP, I figured a quick blog entry would be useful.

The preliminaries

Ok, let's make sure we are all on the same page. The examples I'm describing here use 1.1.0.M3, although the same concepts apply to the 1.0.2 release. The biggest difference is the JSPX tags the Roo team has installed since that release. I'm also using persistence, so go ahead and configure a persistence engine if you're hacking along with me.

Installing webflow

This is easy. Just type 'web flow' in the roo shell, and it will configure it for you. The engine will add the dependencies to the maven pom.xml file, configure web flow settings in webflow-config.xml in the WEB-INF/spring directory. It will also drop a nice sample webflow in the WEB-INF/views/sampleflow directory. If you start your application, you'll also see that the menu includes a "Enter Sampleflow WebFlow" menu item.

What does it mean to me?

Ok, now you're getting impertinent, HTML title h3 - I think my readers are more patient than you. *Ahem* Ok, so if you're already a webflow expert, you are ready to go, jump to "I'm a Web Flow Expert Already!" For the rest of you, read this short primer first.

Web Flow is a state-machine pattern, implemented as a very smart controller, within Spring MVC. You define a "web flow definition" in an XML file, which is defined by a series of states and transitions. If you can diagram a flow chart of how a web application should navigate through a system, you can transform that flow chart directly into a web flow definition.

Take the example flow installed by Roo when you set it up, sampleflow. The webflow file, not very well named, is called 'config-flow.xml':


  <flow xmlns="http://www.springframework.org/schema/webflow"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/webflow 
  http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

  <!-- Is your flow persistent? -->
  <!-- <persistence-context />  -->

   <!-- A sample view state -->
   <view-state id="view-state-1">
     	<transition on="success" to="view-state-2"/>
    	<transition on="cancel" to="end-state"/>
   </view-state>

   <view-state id="view-state-2">
    	<transition on="cancel" to="end-state"/>
   </view-state>

   <!-- A sample end state -->
   <end-state id="end-state" view="end-state"/>

</flow>

Just eyeball that file for a minute. You really don't have to understand a vast and difficult API to interpret it. The view is defined by three states - view-state-1, view-state-2, and end-state. In view-state-1, two transitions are defined - one with an event name of 'success', and one with an event name of 'cancel' - each of these transitions take you to one of the other states. A view-state is a state that renders a view (JSPX file) and awaits your next submission to figure out what event name you wish it to evaluate. So, if you develop a page to display for view-state-1, aptly named view-state-1.jspx, it should give you two actions, each of which should trigger an event allowed by that state.

Getting to Know View, Getting to Know All About View...

Stop cringing. My sense of humor is warped this morning. But, you asked, so here it is - the view state is one of those Roo JSPX view files, which heavily leverages tag libraries. Scan the view-state-1.jspx file below and you'll see two buttons with special names, all posting to a form with no URL:

<div xmlns:spring="http://www.springframework.org/tags" 
  xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
  xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" 
  xmlns:jsp="http://java.sun.com/JSP/Page" 
  version="2.0">
    <jsp:output omit-xml-declaration="yes" />
    <spring:message var="title" code="webflow_state1_title" />
    <util:panel id="title" title="${title}">
      <h1>${fn:escapeXml(title)}</h1>
      <p>
        <spring:message code="webflow_state1_message" />
      </p>
      <form method="POST">
        <div class="submit">
          <spring:message var="cancel" code="button_cancel" />
          <spring:message var="proceed" code="button_proceed" />
          <input type="submit" id="cancel" 
              name="_eventId_cancel" value="${fn:escapeXml(cancel)}" />
          <input type="submit" id="success" 
              name="_eventId_success" value="${fn:escapeXml(proceed)}" />
        </div>
      </form>
    </util:panel>
</div>

Did you see the two submit buttons toward the bottom of the page on lines 17 and 19? Each had a name corresponding to the name of the transition event in the XML web flow document. Also, notice how the form doesn't have an address - in HTML when you leave out the address, it simply posts back to itself, thereby going back to the web flow and evaluating the submitted values. Since you can only click two buttons - _eventId_cancel and _eventId_success, you have two outcomes, which match the two transitions nicely.

More about Web Flow

Web Flow is documented with a user guide over at SpringSource, and there are several books on the subject, including Craig Walls' Spring In Action, which has a MEAP covering Spring 3. SpringSource also delivers training in all Spring-based web technologies in the Spring Rich Web course. Disclosure - my employer, Chariot Solutions, is a SpringSource training partner, and we'll be adding this course by early next year. There is also a user forum. I've left out a ton of information, owing to the fact that I'm spending most of my time writing the book itself, and that I don't have nearly enough time or space to do it justice. However, keep these key things in mind:

  • There are several types of states, including action (execute logic), decision (if/then), and subflow
  • Web Flow keeps track of which flow you are working on by tacking on an Execution ID, which you'll see at the end of an URL. There is a variable you can access in the JSP, ${flowExecutionKey}, that you'll need to tack on as _flowExecutionKey if you write your own URLs in hyperlinks (only important if you are not submitting back to the same form).
  • You want to use Web Flow when you have a multi-step process, and Spring MVC when you don't. Flows have a number of ways to store intermediate data, such as the "flow scope," and you don't want to waste precious memory storing things in there if you don't need to. As with all web applications, think statelessly first, then back your way into needing state.

So, that's it for now. In the Roo book we'll have more, including how to properly work with the tag libraries to build proper links, and a sample that (currently anyway) includes a simple shopping cart flow and a JPA-based object graph to persist the flow. We are releasing an updated MEAP this week, which includes the Spring MVC chapter, so if you want to learn about Roo's controller and view technologies and how the tags function, you can find that information there.

I'm a Web Flow Expert Already!

Then you can pretty much get going! Simply drop new flows in WEB-INF/views, and make sure you include a views.xml file so that Tiles can find your files. By the way, Tiles recently began allowing wildcards, so you can do something like this inside the flow, replacing the path in put-attribute with your own in value below:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
    <definition extends="default" name="*">
        <put-attribute name="body" value="/WEB-INF/views/cart/{1}.jspx"/>
    </definition>
</tiles-definitions>

Do this and you can drop new files into the flow at will, without having to touch your tiles definition.

Enjoy, folks, and sorry if it runs a bit incoherent. This is just a brain dump for now...

Page 1 ... 3 4 5 6 7 ... 9 Next 5 Entries ยป