<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andy Gibson &#187; Spring</title>
	<atom:link href="http://www.andygibson.net/blog/tag/spring/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.andygibson.net/blog</link>
	<description>Open Source Projects &#38; Technical Writings</description>
	<lastBuildDate>Thu, 02 Feb 2012 14:33:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language></language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Implementing Spring MVC with CDI and Java EE 6 part 2</title>
		<link>http://www.andygibson.net/blog/article/implementing-spring-mvc-in-cdi-and-java-ee-6-part-2/</link>
		<comments>http://www.andygibson.net/blog/article/implementing-spring-mvc-in-cdi-and-java-ee-6-part-2/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 12:28:33 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1841</guid>
		<description><![CDATA[In this second article on implementing Spring MVC in Java EE 6 we&#8217;ll take the metadata we extracted in part one and use it to invoke request mapped controller methods in response to web requests and then direct the user to a web page based on the result of the method. In this article we&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>In this second article on implementing Spring MVC in Java EE 6 we&#8217;ll take the metadata we extracted in <a href="http://www.andygibson.net/blog/article/implementing-spring-mvc-with-cdi-and-java-ee-6/">part one</a> and use it to invoke request mapped controller methods in response to web requests and then direct the user to a web page based on the result of the method. <span id="more-1841"></span></p>
<p>In this article we&#8217;ll be implementing the following functions, the code for which is available for <a href='http://www.andygibson.net/blog/wp-content/uploads/2012/01/mvcdi_part2.zip'>download</a> :</p>
<ul>
<li>Write a servlet that will dispatch the requests to our MVC handler class.</li>
<li>In the MVC Handler, we&#8217;ll take a web request and invoke the appropriate controller method</li>
<li>Take the result from the request mapped method and resolve it to a view which the user is forwarded to</li>
</ul>
<h1>Implementing the Servlet</h1>
<p>Our servlet code takes incoming requests and delegates them to the injected <code>MvcHandler</code> instance.</p>
<pre class="brush: java;">@WebServlet(urlPatterns = &quot;/demo/*&quot;)
public class DelegatingServlet extends HttpServlet {

    @Inject
    private MvcHandler mvcHandler;

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doHandleRequest(req, resp, RequestMethod.GET);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doHandleRequest(req, resp, RequestMethod.POST);
    }

    private void doHandleRequest(HttpServletRequest request, HttpServletResponse response,
        RequestMethod requestMethod) {

        mvcHandler.handleRequest(request.getPathInfo(),requestMethod,request,
            response,getServletContext());
    }
}
</pre>
<p>Our servlet uses the <code>@WebServlet</code> annotation to register the servlet for the <code>/demo/*</code> url path. It injects the instance of our <code>MvcHandler</code> class and uses it to handle the <code>GET</code> and <code>POST</code> requests. When we call the MVC handler, we have to pass in multiple objects that will be used by the handler. Looking ahead, we can see this is going to grow since we have controller methods, model values, outcomes and view names to pass around so we&#8217;ll create a new object called a <code>RequestContext</code> that will keep a hold of all these things and we can pass all those items around as a single object. </p>
<p>It makes our method calls look nicer with fewer parameters and we don&#8217;t have to keep adding parameters to methods for each new piece of information needed. Working with a single context means we can break the handler down to a specific set of steps with the product of each method (i.e. fetch model values) being held in the context and used in the next method. It also means we can convert it to an interface and/or abstract some of the information available to provide different implementations (i.e portal version). For now, we just need a basic version with a servlet context, request, response objects. We&#8217;ll also need to store the controller, the controller method and the outcome from that method.</p>
<pre class="brush: java;">public class RequestContext {

    private final ServletContext servletContext;
    private final HttpServletRequest request;
    private final HttpServletResponse response;
    private final RequestMethod requestMethod;
    private Object controller;
    private ControllerMethod method;
    private Object outcome;

    public RequestContext(ServletContext servletContext,
            HttpServletRequest request, HttpServletResponse response,
            RequestMethod requestMethod) {
        this.servletContext = servletContext;
        this.request = request;
        this.response = response;
        this.requestMethod = requestMethod;
    }

    //getters and setters omitted
}
</pre>
<h1>Implementing the MVC Handler</h1>
<p>Going back to our MVC Handler, the code in this class pulls everything together and orchestrates things as it receives calls from the servlet.</p>
<pre class="brush: java;">public class MvcHandler {

    @Inject
    private ControllerInfo controllerInfo;

    @Inject
    private ControllerMethodMatcher matcher;

    @Inject
    private BeanManager beanManager;    

	public void handleRequest(RequestContext context) {

		//find the controller method that best matches the request
		context.setMethod(matcher.findMatching(controllerInfo, context));

		if (context.getMethod() != null) {
			Object controller = locateController(context.getMethod().getControllerClass());
			context.setController(controller);
			// start executing the controller method
			executeControllerMethod(context);
			handleResponse(context);
		} else {
			throw new RuntimeException(&quot;Unable to find method for &quot;
					+ context.getRequestMethod() + &quot; request with url &quot;
					+ context.getPath());
		}
	}

    private void handleResponse(RequestContext context) {
        if (context.getOutcome() instanceof String) {
            String outcome = (String) context.getOutcome();
            String view = &quot;/&quot;+outcome+&quot;.jsp&quot;;
            context.forwardTo(view);
        }
    }

    private Object locateController(Class&amp;lt;?&amp;gt; controllerClass) {
          //returns a bean of type controllerClass from CDI
    }

    private void executeControllerMethod(RequestContext context) {
       //executes the controller method on the controller
    }
}
</pre>
<p>We inject our instance of <code>ControllerInfo</code> which holds all the controller methods and the <code>handleRequest()</code> method is called from the servlet when receives a web request. In order to service the request it takes the following steps :</p>
<ul>
<li>Find a matching controller method for this request. </li>
<li>Locate the controller </li>
<li>Execute the controller method on that controller instance saving the outcome returned from the method. </li>
<li>Handle the correct response back to the user. </li>
</ul>
<p>For now, we are just assuming the controller method returns a string that indicates the view name which we forward to. I added a method to handle forwarding on the request context object.</p>
<h2>Matching Methods</h2>
<p>The <code>ControllerMethodMatcher</code> is an interface that can be used to locate a controller method in the list of controller methods that matches the incoming request info held in the request context</p>
<pre class="brush: java;">public interface ControllerMethodMatcher {
    ControllerMethod findMatching(ControllerInfo info,RequestContext context);
}
</pre>
<p>Our default implementation of this is really simple for now. We iterate through our list of controller methods and check that the request type matches the request method of the incoming request. If it does, then as long as the url path starts with the controller level prefix and ends with the method level suffix, then it is a match. Because we already sorted the controller methods in order of the larger expressions first, we know that the first match we come across is the best for now.</p>
<pre class="brush: java;">public class DefaultControllerMatcher implements ControllerMethodMatcher {

    public ControllerMethod findMatching(ControllerInfo info,RequestContext context) {
        for (ControllerMethod method : info.getControllerMethods()) {
            if (matches(method, context)) {
                return method;
            }
        }
        return null;
    }

    protected boolean matches(ControllerMethod methodToTest, RequestContext context) {
        String path = context.getPath();
        boolean result = methodToTest.matchesRequestMethod(context.getRequestMethod())
            &amp;&amp; (methodToTest.getPrefix() == null || path.startsWith(methodToTest.getPrefix()))
            &amp;&amp; (methodToTest.getSuffix() == null || path.endsWith(methodToTest.getSuffix()));
        return result;
    }
}
</pre>
<p>We can override this class, and re-implement the <code>matches</code> method later on and since we pass in the <code>RequestContext</code> we will have all sorts of information available to us to determine the best match. </p>
<h2>Executing the Controller Method</h2>
<p>We can just use reflection to execute the controller method instance for now. We assume that there are no params for now, that will come later.</p>
<pre class="brush: java;">
private void executeControllerMethod(RequestContext context) {
	Method javaMethod = context.getMethod().getMethod();
	Object outcome = null;
	try {
		outcome = javaMethod.invoke(context.getController());
	} catch (Exception e) {
		e.printStackTrace();
	}
	context.setOutcome(outcome);
}
</pre>
<h2>Seeing it in action</h2>
<p>Finally we can put it all together so we can see it in action in a web application. For now our MVC code is in our web project to make integrating it easier. We can later extract the MVC code to a stand-alone module to use as a library in other projects.  We&#8217;ve already set up a controller and our servlet, now we just need to create a couple of pages based on the string returned from the mapped methods. If we run the application now and go to a url such as <a href="http://localhost:8080/mvcdi/demo/person/list">http://localhost:8080/mvcdi/demo/person/list</a> we will get an error message because <code>listPeople.jsp</code> doesn&#8217;t exist. We&#8217;ll create the following simple jsp pages so we can display something in the browser. Each page just consists of the boilerplate structure and some text that indicates which page we are on.</p>
<pre class="brush: xml;">
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;View Person&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    View Person
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>We do this for the following pages in the root of the web directory.</p>
<ul>
<li><code>viewPerson.jsp</code></li>
<li><code>listPeople.jsp</code></li>
<li><code>updatedPerson.jsp</code></li>
<li><code>editPerson.jsp</code> (see below for additional changes)</li>
</ul>
<p>The one different page is the <code>editPerson.jsp</code> page where we want to put a form containing only a button so we can issue a <code>POST</code> request which maps to the method on the controller that handles the <code>POST</code> request from the <code>editPerson.jsp</code> page and navigates to the <code>updatedPerson.jsp</code> page in response.</p>
<pre class="brush: java;">
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;Editing Person&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        Editing Person
        &lt;form method=&quot;post&quot;&gt;
            Some Form Here&lt;br/&gt;
            &lt;input type=&quot;submit&quot; value=&quot;Update&quot; /&gt;
        &lt;/form&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>If we go to <a href="http://localhost:8080/mvcdi/demo/person/edit">http://localhost:8080/mvcdi/demo/person/edit</a> and click the submit button, we get sent to the page that tells us we just updated someone because that is the page returned from the controller method for the <code>edit</code> path with a <code>POST</code> request method.</p>
<p>You can download (<a href='http://www.andygibson.net/blog/wp-content/uploads/2012/01/mvcdi_part2.zip'>mvcdi_part2.zip</a>) the code for this as a maven project that can run on any Java EE 6 container and has been tested on  both JBoss AS 7 and Glassfish 3.1.1.</p>
<p>This wraps up the second installment of this series on implementing Spring MVC in Java EE 6 and CDI and covers the bulk of the request mapping so we can direct our web requests to controller methods and ultimately to specific pages. Next time we&#8217;ll look at providing model data to the pages.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/implementing-spring-mvc-in-cdi-and-java-ee-6-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementing Spring MVC with CDI and Java EE 6 part 1</title>
		<link>http://www.andygibson.net/blog/article/implementing-spring-mvc-with-cdi-and-java-ee-6/</link>
		<comments>http://www.andygibson.net/blog/article/implementing-spring-mvc-with-cdi-and-java-ee-6/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 12:30:36 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1829</guid>
		<description><![CDATA[One of the opinions I&#8217;ve had over the last couple of years is that Spring makes things look really easy, and CDI is a great dependency injection framework. Throw in this article suggesting you can build your own Java EE 7 and it sounds like a challenge, so for fun, I thought I might have [...]]]></description>
			<content:encoded><![CDATA[<p>One of the opinions I&#8217;ve had over the last couple of years is that Spring makes things look really easy, and CDI is a great dependency injection framework. Throw in this article suggesting you can <a href="http://java.dzone.com/articles/cdi-extensions-you-can-build">build your own Java EE 7</a> and it sounds like a challenge, so for fun, I thought I might have a go at implementing a subset of Spring MVC on top of CDI with Java EE 6.<span id="more-1829"></span></p>
<p>Interestingly, there&#8217;s nothing like Spring MVC for Java EE which is a shame because it is a really good framework. So in this series of articles, I&#8217;ll be covering different aspects of implementing Spring MVC on CDI with the caveat that this won&#8217;t be an exact compatible replica. I&#8217;ll be implementing just enough of each feature to demonstrate that it can be done, but I&#8217;ll leave enough room so that with more work, it can be a more accurate implementation. It goes without saying that these articles assume you are familiar with Spring MVC 3 using annotations and at least a little bit familiar with CDI. I&#8217;ll also mention that the code listed in the articles only contains the code relevant to the implementation for demonstration purposes. I&#8217;ve removed a lot of the null checks and other defensive programming code to make things more readable but they are still present in the final code.</p>
<p>In this first part, we will start by laying all the dull ground work as we capture the metadata from the MVC annotations in the following steps : </p>
<ul>
<li>Define our MVC annotations</li>
<li>Define a class to hold our request mapped methods</li>
<li>Write some code to extract the request mapped methods from a given class and store the metadata</li>
</ul>
<h1>The MVC annotations</h1>
<p>To get started we implement the controller and request mapping annotations which are based on the Spring MVC versions. <code>@Controller</code> marks our classes as MVC controllers that implement MVC methods. Each method that can be mapped to a URL is mapped with the <code>@RequestMapping</code> annotation.</p>
<pre class="brush: java;">@Target({ ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}
</pre>
<p>The request mapping annotation has two attributes (for now), the default <code>value</code> which contains an array of paths that are mapped to this controller or method. For now, we will implement simple path matching, the url must start with the controller path and end with the path defined on the method. We can change to a more complex wildcard/Ant path matching implementation if we want to later. The other attribute on the request mapping is an array of <code>RequestMethod</code> types that indicates the type of requests we want to map to this controller and method. For now, we&#8217;ll just deal with <code>POST</code>, <code>GET</code> and <code>DELETE</code> request types :</p>
<pre class="brush: java;">
public enum RequestMethod {
    POST,GET,DELETE
}
</pre>
<p>Now we can define our request mapping annotation :</p>
<pre class="brush: java;">
@Target({ ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {

    String[] value() default {};
    RequestMethod[] method() default {};
}
</pre>
<p>Armed with our new annotations, we can go ahead and create our first controller :</p>
<pre class="brush: java;">
@Controller
@RequestMapping(&amp;quot;/person/&amp;quot;)
public class PersonController {

    @RequestMapping(&amp;quot;list&amp;quot;)
    public String doListPeople() {
        return &amp;quot;listPeople&amp;quot;;
    }

    @RequestMapping(&amp;quot;view&amp;quot;)
    public String doViewPerson() {
        return &amp;quot;viewPerson&amp;quot;;
    }

    @RequestMapping(value=&amp;quot;edit&amp;quot;,method=RequestMethod.GET)
    public String doGetEditPerson() {
        return &amp;quot;editPerson&amp;quot;;
    }

    @RequestMapping(value=&amp;quot;edit&amp;quot;,method=RequestMethod.POST)
    public String doPostUpdatePerson() {
        return &amp;quot;updatePerson&amp;quot;;
    }
}
</pre>
<p>For now, our controller methods return a String which can be used to determine the final view to render.</p>
<h1>The MVC CDI Handler</h1>
<p>Originally, I considered writing this as a <a href="http://docs.jboss.org/weld/reference/1.0.1-Final/en-US/html/extend.html">CDI extension</a> but felt that it wasn&#8217;t a good match and instead chose to create a managed <code>MvcHandler</code> bean that will be invoked by the servlet and will lazily initialize its own configuration post construction. This led to a more modular design since I could make the <code>MvcHandler</code> the center of the implementation and it let me write it in a purely managed environment saving me from having to deal with some of the limits extension have compared to managed beans.</p>
<p>Technically, when a web request comes in, we could get a list of controllers and iterate through them to find a matching controller and then search for a method on that controller that matches our request. However, I&#8217;m extracting and storing all that metadata on startup since it is more efficient and will allow for more expansion later on. When we start examining different types of metadata, it will get ridiculous doing it all at run time. Also, it lets us optimize a bit since we could have several matches, but some will be better matches than others so we will always need to compare all the controller methods each time a request comes in. Pre-reading it lets us also presort the controller methods into best-fit-first.</p>
<h1>Extracting Controller Metadata</h1>
<p>We&#8217;ll create a class called <code>ControllerInfo</code> that holds the metadata for the controllers. It does this by taking the controller class and iterating through its methods and seeing if they have the request mapping annotation on them. If they do, those methods are added to a list of <code>ControllerMethod</code> objects. This object holds info about a specific mapped method on a controller : </p>
<pre class="brush: java;">
public class ControllerMethod {
    private final String prefix;
    private final String suffix;
    private final RequestMethod[] requestMethod;
    private final Method method;

  //getters and setters
}
</pre>
<p>The prefix is determined from the request mapping path on the controller class, and the suffix is determined from the request mapping on the method. The request method value indicates which kinds of request methods this method can be mapped to (<code>GET</code> or <code>POST</code> requests). The <code>Method</code> object is a java reflection <code>Method</code> instance that we can use to not only define the class method that is mapped, but also reference the declaring class for when we need to locate the controller bean. Since the path value can be an array of strings if a particular method has multiple paths in the value then there will be mulitple <code>ControllerMethod</code> entries, one for each path as the suffix. However, we don&#8217;t split up multiple request method values instead opting to store them as they are as an array.</p>
<pre class="brush: java;">
@Controller
@RequestMapping(&amp;quot;/somePath/&amp;quot;)
public class MyController {

   @RequestMapping(value={&amp;quot;page1.do&amp;quot;,&amp;quot;page2.do&amp;quot;},method={GET,POST})
  public void someMethod() {
     ...
  }
}
</pre>
<p>The above class results in two entries : </p>
<table border=1 width="100%">
<tr>
<th>Prefix</th>
<th>Suffix</th>
<th>Request Methods</th>
<th>Method</th>
</tr>
<tr>
<td><code>/somePath/</code></td>
<td><code>page1.do</code></td>
<td><code>GET,POST</code></td>
<td>MyController.someMethod()</td>
</tr>
<tr>
<td><code>/somePath/</code></td>
<td><code>page2.do</code></td>
<td><code>GET,POST</code></td>
<td>MyController.someMethod()</td>
</tr>
</table>
<p>The reason for this is it lets us optimize the path matching based on the best match first by sorting based on the length of the suffix path. Again, we can improve this ordering later on by using a better path matcher.</p>
<p>Now we&#8217;ve a place to store the controller method information, we can implement the <code>ControllerInfo</code> class which contains the list of Controller method instances:</p>
<pre class="brush: java;">
@ApplicationScoped
public class ControllerInfo {

    private final List&amp;lt;ControllerMethod&amp;gt; controllerMethods = new ArrayList&amp;lt;ControllerMethod&amp;gt;();

    private static final String[] DEFAULT_MAPPING_PATHS = new String[] { &amp;quot;&amp;quot; };

    public static final AnnotationLiteral&amp;amp;lt;Controller&amp;amp;gt; CONTROLLER_LITERAL = new AnnotationLiteral&amp;amp;lt;Controller&amp;amp;gt;() {
        private static final long serialVersionUID = -3226395594698453241L;
    };

    @Inject
    private BeanManager beanManager;

    @PostConstruct
    public void initialize() {
        Set&amp;amp;lt;Bean&amp;amp;lt;?&amp;amp;gt;&amp;amp;gt; controllers = beanManager.getBeans(Object.class,CONTROLLER_LITERAL);
        for (Bean&amp;amp;lt;?&amp;amp;gt; bean : controllers) {
            add(bean.getBeanClass());
        }
        sortControllerMethods();
    }

    private void add(Class&amp;amp;lt;?&amp;amp;gt; clazz) {
    }
}
</pre>
<p>The initialize method is invoked when this bean is first created. As we&#8217;ll see later, this bean is injected into the <code>MvcHandler</code> so this method is only called when needed. It uses the CDI API to locate all beans with a controller qualifier annotation and calls the <code>add(Class&lt;?&gt; clazz)</code> method for each controller class. Finally it makes a call to sort our list of <code>ControllerMethod</code> instances.</p>
<p>In the <code>add</code> method, for the given controller class, we iterate through its methods and see if we can add them as a request mapped method.</p>
<pre class="brush: java;">
private void add(Class&amp;amp;lt;?&amp;amp;gt; clazz) {
    if (clazz.isAnnotationPresent(Controller.class)) {

        Method[] methods = clazz.getMethods();
        String[] controllerPaths = null;

        RequestMapping rm = clazz.getAnnotation(RequestMapping.class);

        if (rm != null) {
            controllerPaths = rm.value();
        }

        // if no paths are specified, then default to one blank path so we always add it
        if (controllerPaths == null || controllerPaths.length == 0) {
            controllerPaths = DEFAULT_MAPPING_PATHS;
        }

        // add methods for each mapped path at the controller level
        for (String prefix : controllerPaths) {
            for (Method m : methods) {
                addMethod(prefix, m);
            }
        }
    }
}

private void addMethod(String prefix, Method javaMethod) {

    RequestMapping mapping = javaMethod.getAnnotation(RequestMapping.class);
    if (mapping != null) {

        String[] paths = mapping.value();

        // if these are blank, fill with defaults
        if (paths == null || paths.length == 0) {
            paths = DEFAULT_MAPPING_PATHS;
        }

        for (String path : paths) {
            controllerMethods.add(new ControllerMethod(javaMethod, prefix,path, mapping.method()));
        }

    }
}
</pre>
<p>The <code>addMethod</code> function will check for a request mapping annotation on the method, extract the metadata and store it in the list.</p>
<p>This about wraps up the first installment which covers the extraction of request mapped methods and storing them for use later on. Next time we&#8217;ll start coding our servlet and core MVC handler that will let us make web requests and invoke the mapped methods on our controller before displaying the appropriate web page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/implementing-spring-mvc-with-cdi-and-java-ee-6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My Framework Picks</title>
		<link>http://www.andygibson.net/blog/article/my-framework-picks/</link>
		<comments>http://www.andygibson.net/blog/article/my-framework-picks/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 14:30:59 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1494</guid>
		<description><![CDATA[When I talked about how Context Matters When Discussing Frameworks I intentionally left out naming any picks because the point of that article wasn&#8217;t to start a framework debate (neither is this one, but at least it will get isolated in here). In this post, I&#8217;ll cover my choice of frameworks. My Personal Choices For [...]]]></description>
			<content:encoded><![CDATA[<p>When I talked about how <a href="http://www.andygibson.net/blog/article/context-matters-when-discussing-frameworks/">Context Matters When Discussing Frameworks</a> I intentionally left out naming any picks because the point of that article wasn&#8217;t to start a framework debate (neither is this one, but at least it will get isolated in here). In this post, I&#8217;ll cover my choice of frameworks.<br />
<span id="more-1494"></span></p>
<h1>My Personal Choices</h2>
<p>For me personally, nothing does Web Applications better than JSF backed by Java EE 6. A year ago I would have said Seam, but Java EE 6 now carries most of the Seam functionality. Java EE 6 with Seam 3 sprinkled in for good measure will rock. (if you think Java EE 6 sucks for not being whole until it has Seam 3 added, think of it more like adding jQuery to your web pages). I do like Wicket, but for me, it&#8217;s one of those that sits in the middle and does a bit of both.  It&#8217;s like riding a bike to the mailbox (only a little bit of overkill), or to the store (better than walking, but still with limits). However, it is a very viable alternative.</p>
<p>For web site type projects, I would look for a framework that is more client oriented since people will want to start leveraging the advancements with HTML 5 and Javascript. I would probably use Spring MVC or at a stretch, possibly Grails. Primarily because it offers a development structure that is not so dissimilar to using JSF, and can include Spring Web Flow for more statefulness. At the same time it lets you get under the hood more with CSS, HTML and JavaScript if you choose to. It also gives you some more deployment options without taking features away. </p>
<p>Note that these are merely my personal choices and their selection says nothing about the choices made by anyone else any more than choosing to drive a Ford is being critical of someone driving a Honda. Similarly, if you think Fords suck, you should have at least have a good reason for believing so, other than you couldn&#8217;t drive one before you learned how to.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/my-framework-picks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Conversational Pitfalls</title>
		<link>http://www.andygibson.net/blog/article/conversational-pitfalls/</link>
		<comments>http://www.andygibson.net/blog/article/conversational-pitfalls/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 01:44:52 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=524</guid>
		<description><![CDATA[Seam conversations have certain rules that you need to be aware of when using them. This article came about because for the last couple of years, the same questions have been asked on the Seam forums regarding conversations. It is also a couple of issues that cropped up while I was working on the Seam [...]]]></description>
			<content:encoded><![CDATA[<p>Seam conversations have certain rules that you need to be aware of when using them. This article came about because for the last couple of years, the same questions have been asked on the Seam forums regarding conversations. It is also a couple of issues that cropped up while I was working on the Seam vs. Spring Web Flow articles. Some of the problems are uncannily similar with similar solutions, so parts of this series may be of interest to non-Seam users. Additionally, it seems like a lot of this stuff will also apply to the conversational pieces of JSR 299 &#8211; Contexts and Dependency Injection which will be a part of JEE 6.<br />
<span id="more-524"></span></p>
<h1>Conversational Fundamentals</h1>
<p>Let&#8217;s start with a fairly descriptive and steady paced description of what conversations are and what they are not. Some of these behaviors are probably more figurative that literal. This mainly applies to Seam, but is also similar to CDI.</p>
<p>Conversations in Seam are like buckets that hold conversational data. A user session has a list of conversation contexts each identified by a conversation Id. A conversation is either long running or temporary and even when you are not in a long running conversation, you are using a temporary conversational context or bucket. The only difference between a long running conversation and a temporary conversation is the boolean <code>longRunning</code> flag on the conversation instance. When you start a conversation, all that happens is the <code>longRunning</code> flag on the conversation is set to true. When you end the conversation, the <code>longRunning</code> flag is cleared. There is no destruction of conversational objects and no clearing out of the conversation. Abandoned long running conversations sit in the conversation list until they time out. Note that in JCDI (JSR 299), the long running flag has been renamed to a <code>isTransient</code> flag on the conversation. </p>
<p>Components that are scoped to the conversation are still held in the conversation context regardless of whether it is long running or temporary. The only difference with a long running conversation is that the id for the conversation is propagated from one page to the next. When the id is propagated, that same conversation &#8216;bucket&#8217; is used by the next page and the objects that were in the previous page are accessible in the new page. In each request, Seam determines if the conversation is long running, and if so, it passes the conversation id to the next page as a parameter. Obviously, this propagation only takes place with faces requests, or GET requests that have special handling like manual conversation propagation or you are using the Seam JSF controls that provide GET requests with automatic conversation propagation. </p>
<p>When rendering a new page, at some point Seam will need to access the conversational context. It does this by looking to see if the request contained a conversation id and if so, looking up the existing conversation context instance for that id. Otherwise, it obtains a new conversation instance with a new conversation Id. When there is no long running conversation, no id is propagated so each page obtains a new conversation instance and Id. When we start a long running conversation Seam will automatically propagate the conversation id from one page to the next for us which is how we write applications with multiple pages using the same conversation. </p>
<p>When you end a conversation, the <code>longRunning</code> flag is set to false and Seam no longer propagates the id from one page to the next. However, when you end a conversation on one page, Seam will still propagate the conversation to the next page one last time. This allows us to carry things like faces messages and any other data over the conversation boundary. This next page gets to use the same conversation instance that just finished outside of the conversation boundary. It has a number of benefits as well as some important consequences that can cause many problems that are tricky to track down.</p>
<p>If you end your conversation and set the <code>before-redirect</code> attribute to true the conversation is ended before the redirect so the conversation id is not propagated and the new page starts with a fresh conversation context. The problem with this is that since there is no propagation of the conversation, faces messages (and any other information you wanted to carry to the new page) is not propagated either. This is to be expected since you explicitly specified that you wanted to end the conversation before the new page.</p>
<p>There are also times when Seam will propagate the conversation from one page to the next when it is not long running. If a redirect is taking place, then Seam promotes the conversation to long running temporarily so the conversation id parameter is passed to the redirect. The conversation is then demoted again to a temporary conversation. This allows items such as faces messages to propagate so you can show messages even after a redirect.</p>
<p>One useful way of seeing which conversation you are using is to add <code>Conversation = #{conversation.id}</code> to your template so you can see what conversation id the page is using. This way you can see whether or not the conversation has propagated and whether you are using the same value from the previous page. If the conversation id on two pages is the same, they are using the same conversation instance and sharing data.</p>
<p>Hopefully, this section has provided enough of an overview into Seam conversations, cleared some of the misconceptions up and will make understanding some of the conversational pitfalls easier.</p>
<h1>Dirty Data</h1>
<p>When you end a conversation, the conversation instance contains multiple pieces of data. Let&#8217;s take the scenario of editing a widget, and clicking save or cancel and being taken back to the widget view page. Our Seam page uses a factory method to generate the <code>#{widget}</code> instance from our <code>WidgetHome</code> bean. We may edit the instance, and post back the changes, and then decide to cancel our changes. At this point, our widget in the conversation is dirty, it has changes made to it that we have cancelled. If we do nothing and just go back to the view page, the conversation will be re-used since we propagate that ended conversation id over one last time. The <code>#{widget}</code> references in the view page will refer to our existing dirty instance in the re-used conversation. Since the variable exists in the conversation already, Seam won&#8217;t call the factory method to get a fresh instance.  As a result our view page shows the dirty instance with all our modifications.</p>
<p>This problem can be solved in a couple of different ways, each with its own problems. The simplest is to use <code>before-redirect=true</code> when ending the conversation. This way our view page won&#8217;t use the dirty data from the ended conversation and it starts with a fresh conversation. This may be a problem though if you are passing the widgetId parameter from the previous page. Pages.xml lets you easily add parameters to redirects, but pageflows don&#8217;t. It also means that you won&#8217;t be able to pass any other data over such as a message to say you have cancelled changes. Another similar, but more forceful, way of doing this is just to have a non-faces &#8216;cancel&#8217; link on your edit page that takes you straight to the edit page with a GET request and passes in the widget Id. In this scenario, the conversation is abandoned since we used a link and it will not propagate the conversation or the associated dirty data over with it, nor can you pass any cancellation messages over.</p>
<p>The other method is to let the view page re-use the conversation, but when the user cancels the changes, actually refresh the entity that has been changed. You create a cancel method on the entity home bean which is called when the user cancels their changes and it will refresh the entity so it is no longer dirty. This has the benefit of causing minimal disruption, but if you have a long chain of objects that ended up dirty, making sure you refresh them all can be tricky. </p>
<h1>Stale Data</h1>
<p>The stale data problem is similar to the dirty data problem except the problem occurs within the same conversation and without ending it. If we have some data in a conversation that depends on other values in the conversation, when those values change, we have to make sure we update our data, otherwise it will become stale. For example a paginated list of sales orders from on an EntityQuery means that we need to get a new set of results when we click next or previous. However, if the results of the query are outjected from the query bean and referenced as <code>#{orderList}</code> in the JSF page, then we will see the stale data problem. The first time we enter the page, the variable <code>#{orderList}</code> doesn&#8217;t exist, so Seam calls the factory for <code>#{orderList}</code> which returns the list of the first 10 results.  Our datatable shows the list of results using the variable <code>orderlist</code>.</p>
<pre class="brush: xml;">
&lt;h:dataTable value=&quot;#{orderList}&quot;&gt;
  &lt;!-- Columns Here --&gt;
&lt;/h:dataTable&gt;
</pre>
<p>The user clicks next in the paginator which does a postback, increases the <code>firstResult</code> value and causes a refresh on the result list referenced by the entity query to show the next 10 results. The page is rendered but the displayed results are exactly the same. We are still looking at the first 10 rows. Why? Because the <code>orderList</code> context variable is used by the view to obtain the list of orders. When the page is rendered the second time, JSF looks for the value of <code>#{orderList}</code> and finds it already exists in the conversational context even though it contains the first 10 results, and not the second 10. Seam has no reason to call the factory method to obtain the latest values. In essence, we have two sets of results, the original set which is referenced by the <code>orderList</code> seam variable, and the current set which is the correct list of results and is held by the query bean. </p>
<p>We have two ways of fixing this problem. The first is to change the value our data table is referencing so it is always referencing the result set on the query bean directly.</p>
<pre class="brush: xml;">
&lt;h:dataTable value=&quot;#{orderQuery.resultList}&quot;&gt;
  &lt;!-- Columns Here --&gt;
&lt;/h:dataTable&gt;
</pre>
<p>With this code, there is no El expression used that can become stale. When the page is re-rendered the table will get the results from the order query directly each time ensuring that the most up to date values are used. This is the easiest solution but it cannot be used if you are using the <code>DataModel</code> annotation since Seam requires you to use the outjected data model variable. In such cases refer to the second solution which is to invalidate the <code>orderList</code> variable when we refresh the search results. This is fairly easy, but requires us to override the <code>refresh</code> method in the entity query. When we refresh the list of orders, we simply remove the <code>#{orderList}</code> context variable. i.e.</p>
<pre class="brush: java;">
@Override
public void refresh()
{
    super.refresh();
    Contexts.removeFromAllContexts(&quot;orderList&quot;);
}
</pre>
<p>This means that when the user causes a refresh of the query data, the variables referencing that data will be ejected from all contexts and the next time that value is requested in a JSF page, the appropriate Seam factory will be called to get the most up to date result set.</p>
<h1>Starting a conversation</h1>
<p>Even starting a conversation can be a problem. In most cases, we utilize the <code>join="true"</code> attribute to gloss over the fact that we are going into a page that requires a conversation with or without a conversation already started. When we hit our target page, we know that we will be in a conversation, either a newly started one, or an existing conversation. We may not care which except that not considering our conversation start and end points has side effects. Using the join attribute is not a substitue for thinking about conversation demarcation.</p>
<p>First is the issue of old data where a new page may re-use data from the last page because they share the conversation. For example, we are viewing a widget and the widget instance is loaded into the temporary conversation. 10 minutes later, we click edit which takes us to the widget edit page and starts a long running conversation. The edit page needs an instance of a widget which it already has from the view page, but this instance of a widget is 10 minutes old and has been edited by another user since you loaded the view page and therefore, you need to do a refresh. This problem arose without us even starting a long running conversation in the view page. The answer here is to ensure that you are always starting with a fresh conversation instance when you go in to the edit page. The easiest way to do that is to use <code>propagation="none"</code> on the link to edit the widget, or just use a plain old GET link.</p>
<p>If a page is meant to start a conversation and also start a pageflow then you cannot enter that page with an existing conversation. If you do, the page will join the existing conversation and the pageflow will not start. Pageflows can only be started with a fresh conversation. Note that initially a page may be simple enough that you don&#8217;t need a pageflow and you could ignore conversation demarcation, but if you later start a pageflow on that page, you could end up with all sorts of headaches as invoking that page from different places may or may not start the pageflow depending on whether the page you were on previously had a long running conversation.</p>
<h1>Menus</h1>
<p>Always consider your menus and their links and what pages they will be used in. They could be called from pages where there may or may not be a long running conversation. Consider whether that conversation is propagated or not. Typically (and luckily) most links in menus are to top level items and thus conversation propagation is never really required which means you can just never propagate it. Propagation is mostly task centric and therefore is more likely to appear in the main page itself rather than a general application wide menu.</p>
<p>One other problem I found was with rich menu items which only allow an action on the menu item. Typically to end or demarcate a conversation, you would need an <code>s:link</code> or <code>s:button</code> since only these Seam specific controls were are aware of the concept of conversation propagation. Since our menu is shared across all pages if we were in a pageflow, we could end up with Illegal Navigation issues since we don&#8217;t account for global menu navigation in our pageflows. Alternatively, we might be in a conversation and calling a page that starts a new conversation with a pageflow so we need to end the conversation before we get there so we can start the new conversation and also the new pageflow. In a nutshell, we need to end any current conversation then re-direct to a new page where we will start a new conversation. We also need to be able to do this from a JSF <code>action</code> since some menu components require actions instead of allowing you to add links.</p>
<p>One solution to this is to use a navigator component that will perform these tasks for us and we just pass in the view-id that we want to go to.</p>
<pre class="brush: java;">
@Name(&quot;navigator&quot;)
@Scope(ScopeType.STATELESS)
public class Navigator {

	public void gotoView(String view) {

		if (Conversation.instance().isLongRunning()) {
			Conversation.instance().end(true);
		}

		Redirect.instance().setViewId(view);
		Redirect.instance().execute();
	}

}
</pre>
<p>With this, we can define our action methods as <code>#{navigator.gotoView("/startBookingProcess")}</code> and when that menu item is selected, it will end the conversation and perform the redirect so on our new page we can start a new conversion and pageflow.</p>
<h1>Conversational Best Practices</h1>
<p>These are best practices that I&#8217;ve found working with Seam and conversations in general. Obviously, it&#8217;s a personal thing, and some people may disagree with me on them, but these rules have served me and my team well.</p>
<p>Always determine where a page fits in terms of conversations and always treat that page the same way. For example, edit and view pages I tend to isolate from other conversations. I tend to only use the temporary conversation for the view page so if you click refresh, it reloads the data which is really what you want, a refreshed view of what you are looking it. Any links to a view (or edit) page do not propagate the conversation at all. </p>
<p>I always start conversations in <code>pages.xml</code> since this provides a single common place to do it. I&#8217;ve never really used the annotations since it requires knowledge of the target page to know which method you need to call. To edit a widget, with pages.xml you can just go to <code>/widgetEdit.seam?widgetId=234</code> as opposed to calling a specific method annotated with <code>@Begin</code>.</p>
<p>Hope this has helped guide you through some of the complexities of conversations in Seam. Once you understand the basic principles, it makes it much easier to figure out why something isn&#8217;t working quite right, and some of these bugs relating to stale and dirty data can be subtle and sneaky.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/conversational-pitfalls/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Notes On Choosing A Web Framework</title>
		<link>http://www.andygibson.net/blog/article/notes-on-choosing-a-web-framework/</link>
		<comments>http://www.andygibson.net/blog/article/notes-on-choosing-a-web-framework/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 13:24:47 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=549</guid>
		<description><![CDATA[I&#8217;m looking at starting a new project and once again find myself choosing between frameworks. Having spent some time evaluating different ones I wrote up some notes to share and get some feedback that might alter my thoughts or opinions. Here&#8217;s the criteria I&#8217;m using to choose a framework in no particular order. IDE Support [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m looking at starting a new project and once again find myself choosing between frameworks. Having spent some time evaluating different ones I wrote up some notes to share and get some feedback that might alter my thoughts or opinions. Here&#8217;s the criteria I&#8217;m using to choose a framework in no particular order.<br />
<span id="more-549"></span></p>
<p><strong>IDE Support</strong> &#8211; I would like to get as much IDE support as possible for auto completion, code validation and general helpfulness.</p>
<p><strong>Resume Building</strong> &#8211; How much demand is there for the skills? I&#8217;m looking to bolster my skills that have wide adoption in the industry. As this is an important factor, it also means I probably won&#8217;t be choosing a framework that I am already very familiar with. I&#8217;ll be using job trends and opinion to determine the industry support for the frameworks. I know job sites aren&#8217;t the best measure, especially since many ads are stuffed with buzzwords so they appear in searches even if there is no JSF, JAXB or JAX-WS involved. However, the fact that they are included at all indicates some kind of market penetration of the technology.</p>
<p><strong>Ajax Support</strong> &#8211; How well does it support Ajax natively out of the box as opposed to requiring third party libraries and are there de-facto standard libraries for that framework if they are needed.</p>
<p><strong>Templating / Layout</strong> &#8211; How are pages built and organized to enable reusable HTML without using include statements everywhere or some other mechanism which will require every page to be edited if the layout is changed. I think facelets is the best page layout library out there as it pulls the template into the page and then pushes the content from the page into the template making separate files optional. Tiles requires separate definition files and does a similar thing outside of the page being rendered. Sitemesh is non invasive and works by decorating existing pages as they are sent to the client. In terms of writing actual pages, the choices are Jsp, Velocity and Freemarker, of which JSP and Velocity are the two most in demand.</p>
<p><strong>Completeness</strong> &#8211; How much is in the framework out of the box without requiring additional libraries for core functionality. Obviously, you are going to need libraries for things like data access, but the framework should be able to put text in a page without requiring third party libraries. One other aspect of this is how easy it is to get up and running without having to get different pieces configured and talking to each other. Some frameworks discussed here like Spring MVC and JSF are not meant to be complete frameworks but a framework onto which to build other frameworks (like Servlets). In these cases, the frameworks are expanded by third party libraries so completeness is not so much a factor here. Third party libraries integrated as part of the stack is acceptable (i.e. Sitemesh in Grails and Richfaces in Seam).</p>
<p><strong>Custom Paginated Tables with Sortable Columns</strong> &#8211; This is my barrier for determining how powerful and easy a framework is to use. Simple CRUD is trivial to write, it&#8217;s like hello world for the web so I usually go for a more robust litmus test by writing some pagination code. Action frameworks require you to chug all the parameters backwards and forwards and handle your own binding and determining whether a page was selected or next/previous was clicked while Component frameworks handle most of that for you. For the same reason, clickable columns can be a real pain. For bonus points, how easy is it to implement multiple paginated / sortable tables? </p>
<p><strong>Statefulness</strong> &#8211; Can we integrate some kind of stateful mechanism in there (i.e Spring Web Flow) cleanly? There are a few scenarios where I will need a stateful workflow in the application.</p>
<p><strong>Third Party Support and integration</strong> &#8211; One annoying aspect of java web development is all the pieces and parts that need to be strung together and then you have to get them to play nicely. This is really about the path of least surprise, and not having to deal with issues because I add libraries that don&#8217;t have special mechanisms for working with each other.. I.e Spring MVC embraces Tiles, but how much of a hassle is it to incorporate Velocity with Tiles? This issue is also somewhat redundant for those frameworks that include built-in solutions for most needs. </p>
<p>The application is going to be moderate in size, but hopefully growing as time goes on. For that reason, I&#8217;m looking for something flexible enough to grow and refactor later on. Initially, I&#8217;m also looking for something lightweight and will be looking to deploy it on Tomcat primarily due to ease of hosting. </p>
<h1>Action or Component Based</h1>
<p>I find Action frameworks are great for catalogs and simple CRUD pages but when you start getting to more complex web applications pages, things get much tricker. Take for example a search page with 10 search parameters, suddenly you find yourself having to attach 10 parameters to the next/previous/first/last result links or using javascript funkiness to modify form contents to change the form state and post the form. Add column ordering and things get pretty messy quickly. In my mind, For a web application, any search pages (or other pages that require pagination or other common interface elements) should be trivial to write within minutes. Obviously, if you are Google and your main business is that one search page, you can afford to spend a little more time on it and be as choosy as you like on how to implement it. However, it never fails to amaze how much code people will write to create a single page demonstrating how to do some simple function in a non-reusable way. User interface elements like pagination and column ordering should be totally reusable. </p>
<h1>The Contenders</h1>
<p>Here are the contenders in no specific order</p>
<ul>
<li>Seam with JSF</li>
<li>Wicket</li>
<li>JSF</li>
<li>Grails</li>
<li>Spring MVC with JSP</li>
<li>Spring MVC with JSF</li>
</ul>
<p>First lets look at the job trends for these different frameworks :</p>
<div style="width:540px">
<a href="http://www.indeed.com/jobtrends?q=spring+java%2C+ejb+java%2C+jsf+java%2C+%22spring+mvc%22+java%2C+wicket+java%2C+seam+java%2C+grails+java" title="spring java, ejb java, jsf java, &#034;spring mvc&#034; java, wicket java, seam java, grails java Job Trends"><br />
<img width="540" height="300" src="http://www.indeed.com/trendgraph/jobgraph.png?q=spring+java%2C+ejb+java%2C+jsf+java%2C+%22spring+mvc%22+java%2C+wicket+java%2C+seam+java%2C+grails+java" border="0" alt="spring java, ejb java, jsf java, &#034;spring mvc&#034; java, wicket java, seam java, grails java Job Trends graph"><br />
</a></p>
<table width="100%" cellpadding="6" cellspacing="0" border="0" style="font-size:80%">
<tr>
<td><a href="http://www.indeed.com/jobtrends?q=spring+java%2C+ejb+java%2C+jsf+java%2C+%22spring+mvc%22+java%2C+wicket+java%2C+seam+java%2C+grails+java">spring java, ejb java, jsf java, &#034;spring mvc&#034; java, wicket java, seam java, grails java Job Trends</a></td>
<td align="right"><a href="http://www.indeed.com/q-spring-java-jobs.html">spring java jobs</a> &#8211; <a href="http://www.indeed.com/q-ejb-java-jobs.html">ejb java jobs</a> &#8211; <a href="http://www.indeed.com/q-jsf-java-jobs.html">jsf java jobs</a> &#8211; <a href="http://www.indeed.com/jobs?q=%22spring+mvc%22+java">&#034;spring mvc&#034; java jobs</a> &#8211; <a href="http://www.indeed.com/q-wicket-java-jobs.html">wicket java jobs</a> &#8211; <a href="http://www.indeed.com/q-seam-java-jobs.html">seam java jobs</a> &#8211; <a href="http://www.indeed.com/q-grails-java-jobs.html">grails java jobs</a></td>
</tr>
</table>
</div>
<p>We can see a sort of multi-tier system in place for different frameworks. Spring and EJB both rank up there as first tier technologies. I&#8217;ve already had quite a bit of experience with both of these but Spring is at an advantage with regards to being lightweight and running in tomcat without having to worry about setting up an embedded EJB container. Writing something with EJB 6 might be a possibility, but I think it more likely I&#8217;ll try and use Spring.</p>
<p>Now lets consider the view frameworks :</p>
<div style="width:540px">
<a href="http://www.indeed.com/jobtrends?q=+jsf+java%2C+%22spring+mvc%22+java%2C+wicket+java%2C+seam+java%2C+grails+java" title="jsf java, &#034;spring mvc&#034; java, wicket java, seam java, grails java Job Trends"><br />
<img width="540" height="300" src="http://www.indeed.com/trendgraph/jobgraph.png?q=+jsf+java%2C+%22spring+mvc%22+java%2C+wicket+java%2C+seam+java%2C+grails+java" border="0" alt="jsf java, &#034;spring mvc&#034; java, wicket java, seam java, grails java Job Trends graph"><br />
</a></p>
<table width="100%" cellpadding="6" cellspacing="0" border="0" style="font-size:80%">
<tr>
<td><a href="http://www.indeed.com/jobtrends?q=+jsf+java%2C+%22spring+mvc%22+java%2C+wicket+java%2C+seam+java%2C+grails+java">jsf java, &#034;spring mvc&#034; java, wicket java, seam java, grails java Job Trends</a></td>
<td align="right"><a href="http://www.indeed.com/q-jsf-java-jobs.html">jsf java jobs</a> &#8211; <a href="http://www.indeed.com/jobs?q=%22spring+mvc%22+java">&#034;spring mvc&#034; java jobs</a> &#8211; <a href="http://www.indeed.com/q-wicket-java-jobs.html">wicket java jobs</a> &#8211; <a href="http://www.indeed.com/q-seam-java-jobs.html">seam java jobs</a> &#8211; <a href="http://www.indeed.com/q-grails-java-jobs.html">grails java jobs</a></td>
</tr>
</table>
</div>
<h1>Seam / JSF</h1>
<p>I&#8217;ve had a lot of experience with these two so it&#8217;s easy to comment on. Great IDE support (probably the best), great out of the box support, but it can feel foreign to use on Tomcat where it doesn&#8217;t offer such a rich a developer experience. Great Ajax support, but not so great for the resume since I already have a lot of experience with Seam and there are very few Seam jobs out there.</p>
<table style="width: 100%; font-size: 90%">
<tr>
<th colspan=4>Seam</th>
</tr>
<tr>
<td><strong>IDE Support</strong></td>
<td>Excellent &#8211; JBoss Tools</td>
<td><strong>Demand</strong></td>
<td>Poor</td>
</tr>
<tr>
<td><strong>Ajax Support</strong></td>
<td>Excellent &#8211; Richfaces</td>
<td><strong>Templating</strong></td>
<td>Excellent &#8211; Facelets</td>
</tr>
<tr>
<td><strong>Pagination</strong></td>
<td>Excellent &#8211; reusable component based pagination</td>
<td><strong>Completeness</strong></td>
<td>Excellent</td>
</tr>
<tr>
<td><strong>Statefullness</strong></td>
<td>Excellent &#8211; Conversational scope</td>
<td><strong>3rd Party Library Integration</strong></td>
<td>Ok &#8211; Seam likes things to run a certain way</td>
</tr>
</table>
<h1>JSF</h1>
<p>Despite using Seam a lot, writing a straight JSF application is still quite different and poses a number of challenges. It might be a interesting using just JSF but I have most of that ground covered with my existing JSF work. JSF is in-demand though and this might be an opportunity to use it with other frameworks such as a Spring/Hibernate/JSF combination. It has great Ajax support with multiple frameworks available, but no decent IDE support even though JBoss Tools works well on plain JSF apps without Seam. It may also get frustrating since I&#8217;ll be having constant reminders of how easy things are when you use Seam. Facelets is a great templating framework, if not the best, and I&#8217;d probably go to JSF 2.0 so I can use annotated beans. For statefulness, I could add in Orchestra and pagination should be simple with JSF although I think Seam (or JBoss-El) added ways to call methods (with parameters) on beans passed in to facelets which made it really easy. I haven&#8217;t been able to duplicate that with in JSF or Spring Faces which could be a problem. One annoyance of JSF is the inability to suppress validation when you post the form back but don&#8217;t want to save it which you may want to do as part of a web flow where you want to save the contents, go to another page, come back and finish your data entry. The only solution is to manually perform validation when the form is finally saved and not use JSF validators which is a limitation and I don&#8217;t thing this was fixed in JSF 2.0.</p>
<table style="width: 100%; font-size: 90%">
<tr>
<th colspan=4>JSF</th>
</tr>
<tr>
<td><strong>IDE Support</strong></td>
<td>Ok with JBoss Tools</td>
<td><strong>Demand</strong></td>
<td>Excellent</td>
</tr>
<tr>
<td><strong>Ajax Support</strong></td>
<td>Great with 3rd Party tools or JSF 2.0</td>
<td><strong>Templating</strong></td>
<td>Excellent &#8211; Facelets</td>
</tr>
<tr>
<td><strong>Pagination</strong></td>
<td>Good</td>
<td><strong>Completeness</strong></td>
<td>Ground framework</td>
</tr>
<tr>
<td><strong>Statefulness</strong></td>
<td>None without 3rd party libs like Apache Orchestra</td>
<td><strong>3rd Party Library Integration</strong></td>
<td>Excellent for JSF libs</td>
</tr>
</table>
<h1>Wicket</h1>
<p>Wicket is a great component based framework with good ajax support, a fine grained stateful architecture and because of it&#8217;s emphasis on the java language, good IDE support. Some people don&#8217;t like the heavy use of java code to build web pages, but it&#8217;s a personal thing and I do enjoy it. However, the only thing holding it back for me is the poor industry adoption with very few Wicket jobs. </p>
<table style="width: 100%; font-size: 90%">
<tr>
<th colspan=4>Wicket</th>
</tr>
<tr>
<td><strong>IDE Support</strong></td>
<td>Great since it is mostly java based</td>
<td><strong>Demand</strong></td>
<td>Poor &#8211; unfortunately</td>
</tr>
<tr>
<td><strong>Ajax Support</strong></td>
<td>Excellent &#8211; it comes with Ajaxified components</td>
<td><strong>Templating</strong></td>
<td>Excellent &#8211; Offers page inheritance and panels</td>
</tr>
<tr>
<td><strong>Pagination</strong></td>
<td>Excellent &#8211; reusable component based pagination</td>
<td><strong>Completeness</strong></td>
<td>Good</td>
</tr>
<tr>
<td><strong>Statefullness</strong></td>
<td>Excellent &#8211; Fine grained statefulness</td>
<td><strong>3rd Party Library Integration</strong></td>
<td>Great &#8211; although you won&#8217;t need or be able to use many web libraries (i.e. tiles, velocity etc) here.</td>
</tr>
</table>
<h1>Grails</h1>
<p>I tried to get back into Grails and again, I hit a number of snags. It&#8217;s a great framework, but I find it can be problematic. The IDE support was basic and I often had to clean the eclipse project then the grails project so it wouldn&#8217;t choke on old classes lying around. Netbeans also has Grails support, but was prone to hanging when you want to restart the server. It also lacked the refactoring / renaming features present in eclipse.  I also found problems in the framework itself such as not being able to model embedded classes that contained a reference to another entity. Other times, inexplicably, when I called <code>person.save()</code> nothing would happen, no error, no messages, nothing. I don&#8217;t doubt it was my fault and something I did, but it is off putting and frustrating in a framework that won&#8217;t tell you when you have a syntax error.</p>
<p>Grails and Wicket seem like polar opposites in some ways. Wicket is all about type safety and strict java code checked by the IDE. Grails on the other hand doesn&#8217;t often know when you make a mistake because its a dynamic language.  Developers shouldn&#8217;t have to write tests just to make sure you didn&#8217;t make any typo&#8217;s in your classes, people have spent a number of years and millions of dollars evolving IDEs to solve that very problem.</p>
<p>The dynamic language is all very nice, and Grails is a framework but when I&#8217;m building furniture, I don&#8217;t start out with aflat pack plywood cabinet and slowly replace each piece with half inch mahogany with hand cut dovetail joints in the name of being rapid and agile (umm, Agile Wordworking, there&#8217;s an idea). I can see the point, and for the most part, Grails is unobtrusive but I think for me,  on this project, I&#8217;d rather start out with a workbench and some planks of mahogany and craft it from scratch. </p>
<p>Ajax support is excellent and it also has many plugins which are easy to install and use. Writing taglibs is a breeze and very intuitive. Even pagination was fairly simple and I especially liked the paginator tag that takes a map of parameter values to include on all the previous/next/page links. Again, things are scarce on the job front for Grails, but being such a unique and productive tool I think there is a great future for Grails which lowers the importance of current trends. </p>
<p>Grails also supports Spring Web Flow but I&#8217;m not sure it allows the use of flow scoped persistence contexts. Sitemesh is used for templating and offers a lot of features out of the box. Overall it&#8217;s very impressive and definitely still a contender.</p>
<table style="width: 100%; font-size: 90%">
<tr>
<th colspan=4>Grails</th>
</tr>
<tr>
<td><strong>IDE Support</strong></td>
<td>Poor</td>
<td><strong>Demand</strong></td>
<td>Small but growing</td>
</tr>
<tr>
<td><strong>Ajax Support</strong></td>
<td>Excellent</td>
<td><strong>Templating</strong></td>
<td>Excellent &#8211; Sitemesh and easy taglibs</td>
</tr>
<tr>
<td><strong>Pagination</strong></td>
<td>Great</td>
<td><strong>Completeness</strong></td>
<td>Great &#8211; plugins make things easier</td>
</tr>
<tr>
<td><strong>statefulness</strong></td>
<td>Spring Web Flow </td>
<td><strong>3rd Party Library Integration</strong></td>
<td>Plugins make it really easy</td>
</tr>
</table>
<h1>Spring MVC with JSP</h1>
<p>This is probably the one I was most eager to tackle as I think this one probably has the most potential. Spring and JSP have been largely adopted within the industry, but are they any good? I think Spring MVC is excellent, especially with the new Spring 2.5 Controller annotations and Web Flow integration. As usual with Spring, it provides a lot of flexibility and it sits on the Core Spring Framework. For templating, I can use Sitemesh, Tiles, and it includes support for velocity and free marker. It appears that using both Tiles and Velocity together isn&#8217;t straightforward resulting in this third party <a href="http://anydoby.com/velocity/">plugin</a> to solve the problem.</p>
<p>Spring MVC doesn&#8217;t have any ajax support, <a href="http://static.springsource.org/spring/docs/2.0.x/reference/mvc.html">Chapter 13 &#8211; Web MVC Framework</a> of the Spring reference documentaton doesn&#8217;t even mention the word Ajax. Spring Web Flow has Ajax support but it requires the use of Tiles (or some other compatible templating library) for specifying page fragments to update. This is also requires that pages be designed in such a way that the Ajax updatable pieces are clearly defined in the page definition which is outside of the page being designed. With Richfaces you can create a fragment in the page just by using an output panel tag and giving it a name. Another problem with Spring Web Flow is the inability to use an Open Session In View alongside the Flow Managed Persistence context which means having to work around Lazy Initialization Issues in other ways. On the plus side though, you can make validation optional in Spring Web Flow if you are using the Spring Validators and not JSF.</p>
<table style="width : 100%;font-size : 90%">
<tr>
<th colspan=4>Spring MVC with JSP </th>
</tr>
<tr>
<td><strong>IDE Support</strong></td>
<td>Good &#8211; Spring IDE</td>
<td><strong>Demand</strong></td>
<td>Excellent</td>
</tr>
<tr>
<td><strong>Ajax Support</strong></td>
<td>Poor</td>
<td><strong>Templating</strong></td>
<td>3rd Party</td>
</tr>
<tr>
<td><strong>Pagination</strong></td>
<td>Roll Your Own</td>
<td><strong>Completeness</strong></td>
<td>Spring MVC offers a solid ground on which to build</td>
</tr>
<tr>
<td><strong>statefulness</strong></td>
<td>Spring Web Flow</td>
<td><strong>3rd Party Library Integration</strong></td>
<td>Good</td>
</tr>
</table>
<h1>Spring MVC with JSF / Spring Faces</h1>
<p>If I couldn&#8217;t find a way to reconcile the problems with Spring MVC and JSP, this would be my backup as it solves a number of problems with using Spring MVC and JSP. It fixes the Ajax and templating issues since I can use a JSF based Ajax framework (IceFaces or Richfaces) and Facelets for superior templating. The only problems here is a resource issue for JSF and the fact that I have already worked with JSF extensively. However, I have found Spring Faces to be a great library to use with some nice extensions. While there are only a few jobs explicitly mentioning Spring Faces, there are many jobs involving Spring and JSF. While spring web flow de-couples your view from the back end, it can be a little too decoupled. For example, within a flow, to call a method from a command button and refresh some data requires you to call the method and return an action string that would trigger the refresh of the data in the web flow. In Seam, you can get away with just calling the method and then refreshing the data. Spring Web Flow, forces you to decouple that which makes for a lot more work when you have multiple links that can trigger a refresh of the data. It also doesn&#8217;t fix the open session in view / flow managed persistence context clash. Writing JSF pages outside of a web flow means having to work directly with Spring beans as Jsf backing beans as opposed to dealing with Spring Beans through the web flow. This isn&#8217;t a big deal though, it just means you have two separate styles of writing code.  Even though Spring Web Flow lets you suppress validations for flow transitions, It doesn&#8217;t have any effect when you are using JSF for the view, only when you are using Spring validations.</p>
<table style="width: 100%; font-size: 90%">
<tr>
<th colspan=4>Spring MVC with JSF / Spring Faces</th>
</tr>
<tr>
<td><strong>IDE Support</strong></td>
<td>Good &#8211; JBoss Tools for JSF and Spring IDE</td>
<td><strong>Demand</strong></td>
<td>Great &#8211; Spring and JSF Combination</td>
</tr>
<tr>
<td><strong>Ajax Support</strong></td>
<td>Excellent</td>
<td><strong>Templating</strong></td>
<td>Excellent &#8211; Facelets</td>
</tr>
<tr>
<td><strong>Pagination</strong></td>
<td>Good</td>
<td><strong>Completeness</strong></td>
<td>Good</td>
</tr>
<tr>
<td><strong>statefulness</strong></td>
<td>Soring Web Flow</td>
<td><strong>3rd Party Library Integration</strong></td>
<td>Good</td>
</tr>
</table>
<h1>Summary</h1>
<p>Ultimately, it boils down to Grails or Spring MVC with JSP and probably Tiles and if I can&#8217;t find a solution there, Spring MVC with JSF. I f career/employment was not a factor, I would pick Wicket with Spring in a second, however, as I&#8217;m looking to bolster my resume and make sure my bona fides are in order for the more popular technologies.</p>
<p>All in all, it&#8217;s a difficult choice, but I&#8217;d love to get some more thoughts on the matter. I&#8217;m sure there are plenty of opinions on frameworks out there in The java community <img src='http://www.andygibson.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
<script type="text/javascript">var dzone_url = 'http://www.andygibson.net/blog/index.php/2009/09/25/notes-on-choosing-a-web-framework/';</script><br />
<script type="text/javascript">var dzone_title = 'Notes On Choosing A Web Framework';</script><br />
<script type="text/javascript">var dzone_blurb = 'Yet another write up of my ongoing evaluation of different web frameworks for a new Java project';</script><br />
<script type="text/javascript">var dzone_style = '1';</script><br />
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/notes-on-choosing-a-web-framework/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Seam vs Spring Web Flow &#8211; vs Wicket</title>
		<link>http://www.andygibson.net/blog/article/seam-versus-spring-web-flow-versus-wicket/</link>
		<comments>http://www.andygibson.net/blog/article/seam-versus-spring-web-flow-versus-wicket/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 00:19:44 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=367</guid>
		<description><![CDATA[In the fifth part of this four part series, I decided to give a non-conversational framework a try and implemented the same application with Wicket which is a semi-stateless framework. (update : If you have already read the previous version only chapter 5 is new and has the Wicket example and final comparison.) Enjoy, HTML [...]]]></description>
			<content:encoded><![CDATA[<p>In the fifth part of this four part series, I decided to give a non-conversational framework a try and implemented the same application with Wicket which is a semi-stateless framework.  </p>
<p>(<b>update</b> : If you have already read the previous version only chapter 5 is new and has the Wicket example and final comparison.)</p>
<p>Enjoy,</p>
<p><a href="http://www.andygibson.net/articles/seam_spring_comparison/html/index.html">HTML</a><br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/html_single/">Single Page HTML</a><br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/pdf/SeamSpringComparison.pdf">PDF</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/seam-versus-spring-web-flow-versus-wicket/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Creating A Spring Web Flow JSF Project From Scratch</title>
		<link>http://www.andygibson.net/blog/tutorial/creating-a-spring-web-flow-jsf-project-from-scratch/</link>
		<comments>http://www.andygibson.net/blog/tutorial/creating-a-spring-web-flow-jsf-project-from-scratch/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 03:07:31 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=216</guid>
		<description><![CDATA[(Updated &#8211; 9 August 2010 &#8211; This was written in my pre-Maven days and after a few requests for working source, I&#8217;ve built the same project using Maven which can be downloaded. Just unzip the maven project, go to the directory in the command line and type mvn jetty:run to start the server and deploy [...]]]></description>
			<content:encoded><![CDATA[<p>(<b>Updated &#8211; 9 August 2010</b> &#8211; This was written in my pre-Maven days and after a few requests for working source, I&#8217;ve built the same project using Maven which can be <a href='http://www.andygibson.net/blog/wp-content/uploads/2009/04/swfproject.zip'>downloaded</a>. Just unzip the maven project, go to the directory in the command line and type <code>mvn jetty:run</code> to start the server and deploy the project. Navigate to <a href="http://localhost:8080/swfproject/home.jsf">http://localhost:8080/swfproject/home.jsf</a> or <a href="http://localhost:8080/swfproject/spring/testFlow">http://localhost:8080/swfproject/spring/testFlow</a> to see the pages demonstrated in the tutorial.</p>
<p>I recently had to start another project using Spring Web Flow and found myself banging my head against a brick wall to get the web flow stuff set up and to request the page properly. As a result, I decided to write up my results as a quick how-to for other developers should they find themselves in the same situation and also as a reference for myself the next time I need to start a Spring Web Flow project using Spring Faces from scratch.This article is meant more of a &#8220;here&#8217;s-how&#8221; as opposed to a &#8220;how-to&#8221; or an &#8220;explain-why&#8221; so we&#8217;ll move at a quick pace with little explanation.<br />
<span id="more-216"></span><br />
For the IDE, I used Eclipse 3.4.1 with Spring IDE plugins version 2.2.1, with Spring 2.5.6 (with dependencies) and Spring Web Flow 2.0.5. You should be able to use SWF 2.0.7 without any problems. For dependencies, I mostly used the ones provided with Spring except for a few, the details of which are included below. Hibernate was used as the JPA implementation and it was all deployed on Tomcat 6.0.18.</p>
<h1>Getting Started</h1>
<p>U started by installing Eclipse and then the Spring plugins. I created a new workspace, and added Tomcat as a server, and created a new dynamic web project. I right clicked on the project to add the Spring nature to the project.<br />
The project will be arranged with multiple Spring configuration files for the database, spring web flow and the main <code>applicationContext.xml</code> to include them in. Flows will be in a directory under <code>/WebContent/WEB-INF/flows</code>.<br />
I started off setting <code>web.xml</code> up with the faces pieces and the Spring MVC dispatcher servlet. </p>
<pre class="brush: xml;">
	&lt;!-- The main config file for this Spring web application --&gt;
	&lt;context-param&gt;
		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
		&lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;!-- Use JSF view templates saved as *.xhtml, for use with Facelets --&gt;
	&lt;context-param&gt;
		&lt;param-name&gt;javax.faces.DEFAULT_SUFFIX&lt;/param-name&gt;
		&lt;param-value&gt;.xhtml&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;!-- Enables special Facelets debug output during development --&gt;
	&lt;context-param&gt;
		&lt;param-name&gt;facelets.DEVELOPMENT&lt;/param-name&gt;
		&lt;param-value&gt;true&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;!-- Causes Facelets to refresh templates during development --&gt;
	&lt;context-param&gt;
		&lt;param-name&gt;facelets.REFRESH_PERIOD&lt;/param-name&gt;
		&lt;param-value&gt;1&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;!-- Loads the Spring web application context --&gt;
	&lt;listener&gt;
		&lt;listener-class&gt;
			org.springframework.web.context.ContextLoaderListener
		&lt;/listener-class&gt;
	&lt;/listener&gt;

	&lt;!-- Serves static resource content from .jar files such as spring-faces.jar --&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;Resources Servlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.js.resource.ResourceServlet
		&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
	&lt;/servlet&gt;

	&lt;!-- Map all /resources requests to the Resource Servlet for handling --&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;Resources Servlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/resources/*&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;!-- The front controller of this Spring Web application, responsible for handling all application requests --&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;Spring MVC Dispatcher Servlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.web.servlet.DispatcherServlet
		&lt;/servlet-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
			&lt;param-value&gt;&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;

	&lt;!-- Map all /spring requests to the Dispatcher Servlet for handling --&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;Spring MVC Dispatcher Servlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/spring/*&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;!-- Just here so the JSF implementation can initialize, *not* used at runtime --&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;

	&lt;!-- Just here so the JSF implementation can initialize --&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;*.jsf&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
</pre>
<p>At the top of this <code>web.xml</code> file, we indicate that our primary Spring bean config file is called <code>\WEB-INF\applicationContext.xml</code> so we navigate to that folder (it&#8217;s in the WebContent folder) and right click and add a new Spring Bean Definition. We also add two other Spring Bean definitions in the same place called <code>dbConfig.xml</code> and <code>flowConfig.xml</code>. These files are defined below :</p>
<p><code>/WebContent/WEB-INF/applicationContext.xml</code> </p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema
/beans/spring-beans.xsd&quot;&gt;

	&lt;import resource=&quot;dbConfig.xml&quot; /&gt;
	&lt;import resource=&quot;flowConfig.xml&quot; /&gt;
&lt;/beans&gt;
</pre>
<p><code>/WebContent/WEB-INF/dbConfig.xml</code> </p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd&quot;&gt;

	&lt;bean id=&quot;entityManagerFactory&quot;
	class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot;&gt;
		&lt;property name=&quot;jpaVendorAdapter&quot;&gt;
			&lt;bean
	class=&quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&quot;&gt;
				&lt;property name=&quot;showSql&quot; value=&quot;true&quot; /&gt;
				&lt;property name=&quot;generateDdl&quot; value=&quot;true&quot; /&gt;
				&lt;property name=&quot;databasePlatform&quot;
	value=&quot;org.hibernate.dialect.MySQLDialect&quot; /&gt;
			&lt;/bean&gt;
		&lt;/property&gt;
		&lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;

	&lt;/bean&gt;

	&lt;bean id=&quot;dataSource&quot; class=&quot;org.apache.commons.dbcp.BasicDataSource&quot;
	destroy-method=&quot;close&quot;&gt;
		&lt;property name=&quot;driverClassName&quot; value=&quot;com.mysql.jdbc.Driver&quot; /&gt;
		&lt;property name=&quot;url&quot; value=&quot;jdbc:mysql://localhost:3306/dbName&quot; /&gt;
		&lt;property name=&quot;username&quot; value=&quot;someUser&quot; /&gt;
		&lt;property name=&quot;password&quot; value=&quot;somePassword&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;transactionManager&quot;
	class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot;&gt;
		&lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;
		&lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot; /&gt;
	&lt;/bean&gt;

	&lt;tx:annotation-driven /&gt;

	&lt;bean
	class=&quot;org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor&quot; /&gt;

&lt;/beans&gt;
</pre>
<p><code>/WebContent/WEB-INF/flowConfig.xml</code> </p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:webflow=&quot;http://www.springframework.org/schema/webflow-config&quot;
	xmlns:faces=&quot;http://www.springframework.org/schema/faces&quot;
	xsi:schemaLocation=&quot;

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/webflow-config

http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd

http://www.springframework.org/schema/faces

http://www.springframework.org/schema/faces/spring-faces-2.0.xsd&quot;&gt;

	&lt;!--Executes flows: the central entry point into the Spring Web Flow system--&gt;
	&lt;webflow:flow-executor id=&quot;flowExecutor&quot;&gt;
		&lt;webflow:flow-execution-listeners&gt;
			&lt;webflow:listener ref=&quot;jpaFlowExecutionListener&quot; /&gt;

		&lt;/webflow:flow-execution-listeners&gt;
	&lt;/webflow:flow-executor&gt;

	&lt;!-- The registry of executable flow definitions --&gt;
	&lt;webflow:flow-registry id=&quot;flowRegistry&quot;
	flow-builder-services=&quot;facesFlowBuilderServices&quot;&gt;
		&lt;webflow:flow-location path=&quot;/WEB-INF/flows/testFlow/testFlow.xml&quot;&gt;&lt;/webflow:flow-location&gt;
	&lt;/webflow:flow-registry&gt;

	&lt;!-- Configures the Spring Web Flow JSF integration --&gt;
	&lt;faces:flow-builder-services id=&quot;facesFlowBuilderServices&quot;
	development=&quot;true&quot; /&gt;

	&lt;!--
		Installs a listener that manages JPA persistence contexts for flows
		that require them
	--&gt;
	&lt;bean id=&quot;jpaFlowExecutionListener&quot;
	class=&quot;org.springframework.webflow.persistence.JpaFlowExecutionListener&quot;&gt;
		&lt;constructor-arg ref=&quot;entityManagerFactory&quot; /&gt;
		&lt;constructor-arg ref=&quot;transactionManager&quot; /&gt;
	&lt;/bean&gt;

	&lt;!-- Maps request URIs to controllers --&gt;
	&lt;bean
	class=&quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&quot;&gt;

		&lt;property name=&quot;mappings&quot;&gt;

			&lt;value&gt;
				/testFlow=flowController
			&lt;/value&gt;
		&lt;/property&gt;
		&lt;property name=&quot;defaultHandler&quot;&gt;
			&lt;!--
				Selects view names to render based on the request URI: e.g. /main
				selects &quot;main&quot;
			--&gt;
			&lt;bean
	class=&quot;org.springframework.web.servlet.mvc.UrlFilenameViewController&quot; /&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

	&lt;!-- Handles requests mapped to the Spring Web Flow system --&gt;
	&lt;bean id=&quot;flowController&quot;
	class=&quot;org.springframework.webflow.mvc.servlet.FlowController&quot;&gt;
		&lt;property name=&quot;flowExecutor&quot; ref=&quot;flowExecutor&quot; /&gt;

	&lt;/bean&gt;

&lt;/beans&gt;
</pre>
<p>Since we are using JPA, we need to include a <code>persistence.xml</code> file to the classpath in <code>src/META-INF/persistence.xml</code>.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot;

	version=&quot;1.0&quot;&gt;

    &lt;persistence-unit name=&quot;default&quot; transaction-type=&quot;RESOURCE_LOCAL&quot; /&gt;

&lt;/persistence&gt;
</pre>
<p>Now we need to add a <code>faces-config.xml</code> in the same location.</p>
<p><code>/WebContent/WEB-INF/faces-config.xml</code> </p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;faces-config version=&quot;1.2&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
	xmlns:xi=&quot;http://www.w3.org/2001/XInclude&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd&quot;&gt;

	&lt;application&gt;
		&lt;el-resolver&gt;org.springframework.web.jsf.el.SpringBeanFacesELResolver&lt;/el-resolver&gt;
		&lt;view-handler&gt;com.sun.facelets.FaceletViewHandler&lt;/view-handler&gt;
	&lt;/application&gt;
&lt;/faces-config&gt;
</pre>
<p>We&#8217;ll also add a html page that redirects to a jsf page immediately. Since we are using facelets, we&#8217;ll also throw in a template to work from. In the WebContent folder, we&#8217;ll add the <code>templates</code> directory to contain our page layout.</p>
<p><code>WebContent\templates\template.xhtml</code> </p>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
                      &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;

  &lt;title&gt;&lt;ui:insert name=&quot;title&quot;&gt;untitled&lt;/ui:insert&gt;&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;
  &lt;h:messages globalOnly=&quot;true&quot; /&gt;

  &lt;ui:insert name=&quot;title&quot;&gt;Title Here&lt;/ui:insert&gt;

  &lt;ui:insert name=&quot;body&quot; /&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Now to add our two pages that will initially launch is into a JSF page.</p>
<p><code>/WebContent/index.html</code></p>
<pre class="brush: xml;">
&lt;html&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Refresh&quot; content=&quot;0; URL=home.jsf&quot;&gt;
&lt;/head&gt;
&lt;/html&gt;
&lt;/textarea&gt; &lt;code&gt;/WebContent/home.xhtml&lt;/code&gt; &lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;
&lt;!DOCTYPE composition PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
                      &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;ui:composition xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	template=&quot;templates/template.xhtml&quot;&gt;

	&lt;ui:define name=&quot;body&quot;&gt;
		&lt;h:form&gt;

			&lt;h:outputText value=&quot;Hello From JSF!&quot; /&gt;

		&lt;/h:form&gt;
	&lt;/ui:define&gt;
&lt;/ui:composition&gt;
</pre>
<p>One more configuration file we need is for Log4j to get rid of the warnings that it has not been set up correctly. The properties file goes in the <code>src</code> directory.</p>
<p><code>/src/log4j.properties</code></p>
<pre class="brush: plain;">
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=info, stdout
log4j.category.org.springframework=WARN
log4j.category.org.hibernate=WARN
</pre>
<p>Now let&#8217;s look at libraries. There are a bunch of libraries that are needed since we haven&#8217;t added any yet.</p>
<table style="font-family: sans-serif; font-size: 12px">
<tr>
<th colspan="2">Libraries located in <code>/WebContent/WEB-INF/lib/</code> </th>
</tr>
<tr>
<td>antlr-2.7.6.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>cglib-nodep-2.1_3.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>commons-beanutils.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>commons-collections.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>commons-dbcp.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>commons-digester.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>commons-logging.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>commons-pool.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>dom4j-1.6.1.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>hibernate3.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>hibernate-annotations.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>hibernate-commons-annotations.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>hibernate-entitymanager.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>javaee.jar</td>
<td>Obtained From Glassfish</td>
</tr>
<tr>
<td>javassist-3.4.GA.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>jboss-el.jar</td>
<td>Obtained From JBoss Seam</td>
</tr>
<tr>
<td>jsf-api.jar</td>
<td>Downloaded Mojarra 1.2_11</td>
</tr>
<tr>
<td>jsf-facelets.jar</td>
<td>Obtained From JBoss Seam</td>
</tr>
<tr>
<td>jsf-impl.jar -</td>
<td>Downloaded Mojarra 1.2_11</td>
</tr>
<tr>
<td>log4j-1.2.15.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>mysql-connector-java-5.0.4-bin.jar</td>
<td>Downloaded from MySQL</td>
</tr>
<tr>
<td>org.springframework.binding-2.0.5.RELEASE.jar</td>
<td>Spring Web Flow Download</td>
</tr>
<tr>
<td>org.springframework.faces-2.0.5.RELEASE.jar</td>
<td>Spring Web Flow Download</td>
</tr>
<tr>
<td>org.springframework.js-2.0.5.RELEASE.jar</td>
<td>Spring Web Flow Download</td>
</tr>
<tr>
<td>org.springframework.webflow-2.0.5.RELEASE.jar</td>
<td>Spring Web Flow Download</td>
</tr>
<tr>
<td>persistence.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>slf4j-api-1.5.0.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>slf4j-log4j12-1.5.0.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>spring.jar</td>
<td>Spring Dependencies</td>
</tr>
<tr>
<td>spring-webmvc.jar</td>
<td>Spring Dependencies</td>
</tr>
</table>
<p>One reason I downloaded the latest JSF version was because I was having problems with the JSF version I was using. The SpringBeanELResolver was being ignored at run-time, it didn&#8217;t even blink if I set it to an undefined class name, however the Spring Delegating variable resolver was working, but the IDE was saying it was deprecated. Once I upgraded to JSF 1.2_11, the EL resolver worked fine. I&#8217;m wondering if an old 1.1 JSF version had crept in there.</p>
<p>Depending on where you end up deploying your application (i.e.Glassfish), you may end up having to remove some of these libraries if they are already installed on the server. In this case, I was using Apache 6.0.18 with a clean install, and therefore with no libraries added to the server.</p>
<h1>Creating a Flow</h1>
<p>Now we should have a working application all ready to go. To test this, we&#8217;ll add a little code and a test page just to verify that everything is working ok. Create a new class called <code>MessageHolder</code> in a package called <code>swfproject</code>. This is a simple class that contains a string that can be set and retrieved from our pages.</p>
<p><code>/src/swfproject/MessageHolder.java</code> </p>
<pre class="brush: java;">
package swfproject;

public class MessageHolder implements Serializable {

	private String text = &quot;Hello From the Message Holder&quot;;

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
}
</pre>
<p>Now we define the bean in the <code>/WEB-INF/applicationContext.xml</code> so we can call the bean from a regular jsf page, or a flow page. </p>
<pre class="brush: xml;">
	&lt;bean name=&quot;springMessage&quot; class=&quot;swfproject.MessageHolder&quot;&gt;
		&lt;property name=&quot;text&quot; value=&quot;This was defined in Spring&quot; /&gt;
	&lt;/bean&gt;
</pre>
<p>In the <code>home.xhtml</code> page, we add the following line to the page, somewhere between the <code>ui:define</code> tag on the page to display the message</p>
<pre class="brush: plain;">
Message is : #{springMessage.text}
</pre>
<p>If you start Tomcat, assuming you have already attached the project to the server if you are using an IDE, and go to <code>http://localhost:8080/projectName/</code> you should redirect to <code>home.jsf</code> and it should the message that was defined in Spring.</p>
<p>Now let&#8217;s add a simple flow called testFlow. If you look in the <code>flowConfig.xml</code> file, there is already a mappings property where we already defined <code>/testFlow=flowController</code>. This means that when this url is requested, the <code>flowController</code> bean instance deals with it.</p>
<p>We need to create a new directory under <code>/WebContent/WEB-INF/flows/</code>, and in there, we need to create a directory called <code>testFlow</code>. In that, we add a page called <code>testFlow.xhtml</code> and <code>testFlow.xml</code>. This is the view and the flow defined respectively.<br />
<code>/WebContent/WEB-INF/flows/testFlow/testFlow.xml</code> Flow </p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;flow xmlns=&quot;http://www.springframework.org/schema/webflow&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:faces=&quot;http://www.springframework.org/schema/faces&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/webflow

http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd&quot;

	start-state=&quot;testFlow&quot;&gt;

	&lt;var name=&quot;flowMessage&quot; class=&quot;swfproject.MessageHolder&quot; /&gt;
	&lt;view-state id=&quot;testFlow&quot;&gt;
		&lt;transition on=&quot;post&quot; to=&quot;testFlow&quot; /&gt;
	&lt;/view-state&gt;
&lt;/flow&gt;
</pre>
<p><code>/WebContent/WEB-INF/flows/testFlow/testFlow.xhtml</code> View </p>
<pre class="brush: xml;">
&lt;!DOCTYPE composition PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
                      &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;ui:composition xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	template=&quot;/templates/template.xhtml&quot;&gt;

	&lt;ui:define name=&quot;body&quot;&gt;
		&lt;h:form&gt;
			&lt;h:outputText value=&quot;This is a test flow&quot; /&gt;
			&lt;br /&gt;
			Message From Spring = #{springMessage.text}&lt;br /&gt;
			Message From Flow = #{flowMessage.text}&lt;br /&gt;
			&lt;h:inputText value=&quot;#{flowMessage.text}&quot; style=&quot;width:200px&quot; /&gt;
			&lt;h:commandButton action=&quot;post&quot; value=&quot;Update&quot; /&gt;
 		&lt;/h:form&gt;
	&lt;/ui:define&gt;
&lt;/ui:composition&gt;
</pre>
<p>Now if you go to <code><a href="http://localhost:8080/app_name/spring/testFlow">http://localhost:8080/app_name/spring/testFlow</a></code> (<b>Remember to replace <code>app_name</code> with your project name</b>) you should see the page we have made as part of our flow. It displays the message from the <code>springMessage</code> instance of the <code>MessageHolder</code> that contains the message from spring. I now also displays the instance from the flow which contains the default message displayed since the flow variable hasn&#8217;t had the text property changed. Also, the URL should change to <code>http://localhost:8080/app_name/spring/testFlow?execution=e3s1</code> or something similar with the execution on the end. This page demonstrates that we will have access to the spring beans, as well as access to variables defined in a flow which is where <code>flowMessage</code> is defined. You can edit the message and click post to change the flowMessage text value. You can open the link up in two browser windows or tabs and see how the two values can be edited independently, and the flowMessage variable is scoped to the flow in the browser.<br />
From this point, you can go ahead and move on with the application all you like. You can change the flow mappings, put in wildcarded flow locations, even get started with trying out Spring MVC (as I plan to). Hope you find this useful as a quick start guide to getting a JSF Spring Web Flow project up and running, as well as defining flows and calling them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/tutorial/creating-a-spring-web-flow-jsf-project-from-scratch/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Seam vs Spring Web Flow Part 4 &#8211; Conclusion</title>
		<link>http://www.andygibson.net/blog/article/seam-vs-spring-web-flow-part-4-conclusion/</link>
		<comments>http://www.andygibson.net/blog/article/seam-vs-spring-web-flow-part-4-conclusion/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 03:43:05 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=185</guid>
		<description><![CDATA[The last installment is finally ready. After many a re-write and consideration of all the issues to come to a fair conclusion, especially as new versions were coming out and new features are being added, I&#8217;m finally able to publish it. Framework Comparisons &#8211; are they ever completed? Anyways, here it is in all it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>The last installment is finally ready. After many a re-write and consideration of all the issues to come to a fair conclusion, especially as new versions were coming out and new features are being added, I&#8217;m finally able to publish it. Framework Comparisons &#8211; are they ever completed? Anyways, here it is in all it&#8217;s &#8230;.well, it&#8217;s here. Enjoy.</p>
<p><a href="http://www.andygibson.net/articles/seam_spring_comparison/html/index.html">HTML</a><br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/html_single/">Single Page HTML</a><br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/pdf/SeamSpringComparison.pdf">PDF</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/seam-vs-spring-web-flow-part-4-conclusion/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Spring vs Seam Part 4 &#8211; Coming Soon (honest)</title>
		<link>http://www.andygibson.net/blog/personal/spring-vs-seam-part-4-coming-soon-honest/</link>
		<comments>http://www.andygibson.net/blog/personal/spring-vs-seam-part-4-coming-soon-honest/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 04:25:32 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=163</guid>
		<description><![CDATA[I know it has been a while since I pushed out my last piece on Spring Web Flow vs Seam, but I am still trying to get it ready. With Christmas, software releases at work leading to a hectic work schedule, and other stuff I have limited time. Furthermore, I am still re-writing parts of [...]]]></description>
			<content:encoded><![CDATA[<p>I know it has been a while since I pushed out my last piece on Spring Web Flow vs Seam, but  I am still trying to get it ready. With Christmas,  software releases at work leading to a hectic work schedule, and other stuff I have limited time. Furthermore, I am still re-writing parts of it, and I end up digressing into related info that is not central to the piece. Also, I am still having difficulty accurately writing up the final conclusion in a fair, and informed manner.<br />
However, hopefully, I will get it completed in the next week here and I can get it released. I may also have some additional material for blog posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/personal/spring-vs-seam-part-4-coming-soon-honest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seam vs Spring Web Flow part 3</title>
		<link>http://www.andygibson.net/blog/article/seam-vs-spring-web-flow-part-3/</link>
		<comments>http://www.andygibson.net/blog/article/seam-vs-spring-web-flow-part-3/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 14:34:36 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=156</guid>
		<description><![CDATA[This is the third of a four part series comparing Seam vs Spring Web Flow (SWF),and looks at the Seam implementation of the sample application. (Updated 1/19/2009 : Changed links to point to the whole set of articles) HTML Single Page HTML PDF]]></description>
			<content:encoded><![CDATA[<p>This is the third of a four part series comparing Seam vs Spring Web Flow (SWF),and looks at the Seam implementation of the sample application.</p>
<p>(Updated 1/19/2009 : Changed links to point to the whole set of articles)<br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/html/index.html">HTML</a><br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/html_single/">Single Page HTML</a><br />
<a href="http://www.andygibson.net/articles/seam_spring_comparison/pdf/SeamSpringComparison.pdf">PDF</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/seam-vs-spring-web-flow-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

