<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Simon Brown&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/" />
<modified>2006-03-24T23:02:09Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/simongbrown/76</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2006, simongbrown</copyright>
<entry>
<title>Comparing webapp frameworks : WebWork</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2006/03/comparing_webap_10.html" />
<modified>2006-03-24T23:02:09Z</modified>
<issued>2006-03-24T23:02:00Z</issued>
<id>tag:weblogs.java.net,2006:/blog/simongbrown/76.4377</id>
<created>2006-03-24T23:02:00Z</created>
<summary type="text/plain">Like Struts, WebWork is a  framework that is fairly established within the J2EE webapp space although it&apos;s interesting that I&apos;ve only ever come across two types of WebWork users - those that have never heard of it and those that love it.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
Like Struts, <a href="http://www.opensymphony.com/webwork">WebWork</a> is a  framework that is fairly established within the J2EE webapp space although it's interesting that I've only ever come across two types of WebWork users - those that have never heard of it and those that love it. WebWork, like most other frameworks, is designed around the web MVC pattern and uses the command and controller implementation strategy. What's slightly different about WebWork is that it's built on top of XWork, a separate framework that provides an implementation of the command pattern that is independent of the Servlet API.
</p>

<p>
In XWork, actions (or commands, depending on your terminology) implement the <code>com.opensymphony.xwork.Action</code> interface, which specifies a single zero argument method called <code>execute()</code>. Since this same interface is used in WebWork, it's possible to write actions without knowledge that they are even running within the context of a web application. From a testability perspective this is very desirable since it allows you to simply instantiate actions and execute them. Of course, most actions typically tend to operate upon data provided as parameters in the HTTP request and, like <a href="http://weblogs.java.net/blog/simongbrown/archive/2006/03/comparing_webap_9.html">Stripes</a>, WebWork actions declare their dependency on those parameters by providing JavaBeans style properties with the same names. At runtime, WebWork automatically extracts parameters from the HTTP request and injects them into your actions. While you can get access to the Servlet API inside of a WebWork action, WebWork doesn't force this upon you, leaving that choice to you as the developer.
</p>

<p>
Right, let's get on with seeing how a WebWork implementation of the sample application compares to the others. I'm using WebWork 2.1.7 and installing it is a simple matter of copying a few JAR files into the <code>/WEB-INF/lib</code> directory and adding the front controller component and WebWork tag library into the <code>web.xml</code> file as follows.
</p>

<pre class="codeSample">&lt;servlet&gt;
  &lt;servlet-name&gt;webwork&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.opensymphony.webwork.dispatcher.ServletDispatcher&lt;/servlet-class&gt;
  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;

&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;webwork&lt;/servlet-name&gt;
  &lt;url-pattern&gt;*.action&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;

&lt;taglib&gt;
  &lt;taglib-uri&gt;webwork&lt;/taglib-uri&gt;
  &lt;taglib-location&gt;/WEB-INF/lib/webwork-2.1.7.jar&lt;/taglib-location&gt;
&lt;/taglib&gt;</pre>

<p>
Two additional configuration files that we need are called <code>validators.xml</code> and <code>xwork.xml</code>. The first of these defines a number of validator components that can be used by the framework to validate incoming requests through an interceptor. Each action can define it's own set of specific validation rules based upon the validators configured in the <code>validators.xml</code> file. Since this is a readonly webapp, we don't really have any need for validation, but we'll be coming back to this when we add some user interactivity. For now, we don't need to declare any validators so the file looks as follows.
</p>

<pre class="codeSample">&lt;!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd"&gt; 

&lt;validators&gt; 
&lt;/validators&gt;</pre>

<p>
The other file (<code>xwork.xml</code>) defines the actions that our web application will use, along with their outcomes/results and the type of view component that is responsible for rendering those outcomes. If you've read <a href="http://weblogs.java.net/blog/simongbrown/archive/2006/01/comparing_webap_7.html">Comparing Webapp Frameworks : Struts</a> or are familiar with Struts, you can think of this as being similar to the <code>struts-config.xml</code> file. Let's see this in action by diving into the code.
</p>

<p>
<b>Home page</b></br />
The home page presents the user a list of recent blog entries and with WebWork, the code that finds these blog entries get wrappeds up inside an XWork action as follows.
</p>

<pre class="codeSample">package action;

import com.opensymphony.xwork.ActionSupport;
import domain.Blog;
import domain.BlogService;

/**
 * Action responsible for finding blog entries, ready to be displayed.
 *
 * @author    Simon Brown
 */
public class ViewBlogEntriesAction extends ActionSupport {

  /** the blog that owns the blog entries */
  private Blog blog;

  /**
   * Performs the processing associated with this action.
   *
   * @return  a String defining the outcome of this action
   */
  public String execute() throws Exception {

    BlogService blogService = new BlogService();
    this.blog = blogService.getBlog();

    return SUCCESS;
  }

  /**
   * Gets the blog that this action is operating upon.
   *
   * @return  a Blog instance
   */
  public Blog getBlog() {
    return blog;
  }

}</pre>

<p>
This implementation is very straightforward, just looking up the <code>Blog</code> instance and returning the predefined <code>SUCCESS</code> outcome. Notice here that the <code>Blog</code> instance isn't inserted into the HTTP request. Instead it's assigned to an instance variable and we'll be seeing shortly how exactly this is used in the JSP page representing the view. Speaking of which, how does the <code>SUCCESS</code> outcome get mapped to that JSP? Here's where the <code>xwork.xml</code> file fits in.

<pre class="codeSample">&lt;!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" 
  "http://www.opensymphony.com/xwork/xwork-1.0.dtd"&gt;

&lt;xwork&gt;
  &lt;include file="webwork-default.xml" /&gt;

  &lt;package name="default" extends="webwork-default"&gt;

    &lt;default-interceptor-ref name="defaultStack" /&gt;

    &lt;action name="viewBlogEntries" class="action.ViewBlogEntriesAction"&gt;
        &lt;result name="success" type="dispatcher"&gt;viewBlogEntries.jsp&lt;/result&gt;
    &lt;/action&gt;

  &lt;/package&gt;
&lt;/xwork&gt;</pre>

<p>
Here, an action called <code>viewBlogEntries</code> is defined (which maps onto a URI of <code>/viewBlogEntries.action</code>) and given the fully qualified name of the class that implements the action. In addition to this, the possible outcomes of the action are defined, mapping a simple string value onto the name of the JSP page that is responsible for rendering that particular outcome. The value of the <code>type</code> attribute instructs WebWork to use the Servlet request dispatcher and, as we'll see in the next blog entry, there are some other possible values that allow you to use alternative view technologies. So, what does the JSP page look like? Well it's pretty similar to the previous versions although I've chosen to show the WebWork tag library in use. It is also possible to use a pure JSP/JSTL combination.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="webwork" prefix="ww" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;&lt;ww:property value="blog.name" /&gt;&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;&lt;ww:property value="blog.name" /&gt;&lt;/h1&gt;
      &lt;h2&gt;&lt;ww:property value="blog.description" /&gt;&lt;/h2&gt;

      &lt;ww:iterator id="blogEntry" value="blog.blogEntries"&gt;
        &lt;div class="blogEntry"&gt;
          &lt;h3&gt;&lt;ww:property value="title"/&gt;&lt;/h3&gt;

          &lt;ww:if test="excerpt != null"&gt;
            &lt;ww:property value="excerpt"/&gt;
            &lt;p&gt;
            &lt;a href="&lt;ww:url value="'viewBlogEntry.action'"&gt;
              &lt;ww:param name="'id'" value="id"/&gt;
            &lt;/ww:url&gt;"&gt;Read more&lt;/a&gt;
            &lt;/p&gt;
          &lt;/ww:if&gt;
          &lt;ww:else&gt;
            &lt;ww:property value="body"/&gt;
          &lt;/ww:else&gt;

          &lt;p&gt;
            Posted on &lt;ww:property value="date" /&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/ww:iterator&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
If you're familiar with something like the Struts bean/logic tags or JSTL, you'll probably pick up the WebWork tags pretty quickly. <code>ww:property</code> outputs the value of the named property, <code>ww:if</code> lets you perform conditional logic and <code>ww:iterator</code> provides a simple looping mechanism. You may be wondering exactly where the <code>blog</code> object comes from since we never injected it into the HTTP request or the JSP page. Behind the scenes, WebWork uses something called a Value Stack to maintain references to objects and make them available within the various supported view technologies. You can think of the value stack as a collection of objects, and one of those objects is the action that was responsible for dispatching us to the page. Accessing objects within the stack is achieved using a language called OGNL (the <a href="http://www.ognl.org/">Object Graph Navigation Language</a>). During the dispatching process, the action becomes the "root" node, meaning you can easily access any properties of the action with a simple <code>object.property</code> syntax. Something worth pointing out is that when you use the <code>ww:iterate</code> tag, the "current object" in the value stack changes to reflect the current object exposed during iteration, but you can get back to any object in the stack by prefixing the expression with the # character.
</p>

<p>
<b>Blog entry detail page</b><br />
At a high level, that's pretty much it so it won't surprise you that the blog entry detail page is very similar. First the action class.
</p>

<pre class="codeSample">package action;

import com.opensymphony.xwork.ActionSupport;
import domain.Blog;
import domain.BlogEntry;
import domain.BlogService;

/**
 * Responsible for finding a specific blog entry.
 *
 * @author    Simon Brown
 */
public class ViewBlogEntryAction extends ActionSupport {

  /** the ID of the blog entry to display */
  private String id;

  /** the blog that owns the blog entries */
  private Blog blog;

  /** the blog entry to be displayed */
  private BlogEntry blogEntry;

  /**
   * Performs the processing associated with this action.
   *
   * @return  a String defining the outcome of this action
   */
  public String execute() throws Exception {
    BlogService blogService = new BlogService();
    blog = blogService.getBlog();
    blogEntry = blog.getBlogEntry(id);

    if (blogEntry == null) {
      return "notfound";
    } else {
      return SUCCESS;
    }
  }

  /**
   * Setter for the id property.
   *
   * @param id    a String
   */
  public void setId(String id) {
    this.id = id;
  }

  /**
   * Gets the blog that this action is operating upon.
   *
   * @return  a Blog instance
   */
  public Blog getBlog() {
    return blog;
  }

  /**
   * Gets the blog entry to be displayed.
   *
   * @return  a BlogEntry instance
   */
  public BlogEntry getBlogEntry() {
    return blogEntry;
  }

}</pre>

<p>
Next up is the fragment of XML that needs to be inserted into the <code>xwork.xml</code> file to register the action and define its outcomes.
</p>

<pre class="codeSample">    &lt;action name="viewBlogEntry" class="action.ViewBlogEntryAction"&gt;
      &lt;result name="success" type="dispatcher"&gt;viewBlogEntry.jsp&lt;/result&gt;
      &lt;result name="notfound" type="dispatcher"&gt;404.jsp&lt;/result&gt;
    &lt;/action&gt;</pre>

<p>
And finally is the JSP page itself.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="webwork" prefix="ww" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;&lt;ww:property value="blogEntry.title" /&gt; : &lt;ww:property value="blog.name" /&gt;&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;&lt;ww:property value="blog.name" /&gt;&lt;/h1&gt;
      &lt;h2&gt;&lt;ww:property value="blog.description" /&gt;&lt;/h2&gt;

      &lt;div class="blogEntry"&gt;
        &lt;h3&gt;&lt;ww:property value="blogEntry.title" /&gt;&lt;/h3&gt;

        &lt;ww:property value="blogEntry.body" /&gt;

        &lt;p&gt;
        Posted on &lt;ww:property value="blogEntry.date" /&gt;
        &lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
<b>Summary</b><br />
Where actions in frameworks like Struts only have responsibility for the business logic associated with processing a request, in WebWork (and Stripes) those actions also act as custodians for the data used in processing the request. Incoming data on the request gets automatically mapped onto JavaBean properties on the action class, which can subsequently be accessed and displayed in the various view technologies. If you're not used to this approach, it <i>can</i> seem a little odd at first. However, it doesn't take very long to get used to and having both the logic and data in the same place proves very useful to support a hierarchy of similar actions. All in all, WebWork is a very sophisticated web application framework that lets you build easily testable actions and provides a way for you to use multiple view technologies. In the next comparison, we'll take a break from JSP to look at another WebWork implementation that uses Velocity.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Stripes</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2006/03/comparing_webap_9.html" />
<modified>2006-03-10T14:06:14Z</modified>
<issued>2006-03-10T14:06:02Z</issued>
<id>tag:weblogs.java.net,2006:/blog/simongbrown/76.4288</id>
<created>2006-03-10T14:06:02Z</created>
<summary type="text/plain">Stripes is a relatively new web application framework that&apos;s been built with a couple of things in mind - simplicity and the adoption of new technology.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
<a href="http://stripes.mc4j.org">Stripes</a> is a relatively new web application framework that's been built with a couple of things in mind - simplicity and the adoption of new technology. In Stripes, you won't find any complex XML configuration files and, refreshingly, the distribution only requires/includes a small number of dependent JAR files. Stripes is a genuinely lightweight framework and uses Java 5 annotations as it's configuration mechanism.
</p>

<p>
Like other webapp frameworks, Stripes sticks to the typical model 2 architecture, implemented using the command and controller strategy where the main front controller component delegates request processing responsibility to an action class. However, unlike most other frameworks, you aren't restricted to implementing a specific <code>execute()</code> method and each action class can provide implementations for more than a single request. Let's see how this looks with an example. I'm using Stripes 1.2.2.
</p>

<p>
<b>Home page</b>
<br />
To recap, the home page presents the user with a list of the most recent blog entries and it's the piece of code that locates those blog entries that is a candidate for moving into an action. We've seen this already with the Struts implementation, so how does this look in Stripes?
</p>

<pre class="codeSample">package action;

import domain.*;
import net.sourceforge.stripes.action.*;

/**
 * A Stripes ActionBean that is responsible for allowing the
 * user to view all recent blog entries.
 *
 * @author    Simon Brown
 */
@UrlBinding("/viewBlogEntries.action")
public class ViewBlogEntriesActionBean implements ActionBean {

  private ActionBeanContext context;

  public ActionBeanContext getContext() {
    return context;
  }

  public void setContext(ActionBeanContext context) {
    this.context = context;
  }

  @DefaultHandler
  @DontValidate
  public Resolution viewBlogEntries() {
    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    context.getRequest().setAttribute("blog", blog);

    return new ForwardResolution("/viewBlogEntries.jsp");
  }

}</pre>

<p>
First up, we need to implement an interface called <code>ActionBean</code>. From the Javadoc...
</p>

<blockquote>
Interface for all classes that respond to user interface events. Implementations receive information about the event (usually a form submission) in two ways. The first is through a ActionBeanContext object which will always be set on the ActionBean prior to any user implemented "handler" methods being invoked. The second is through the setting of JavaBean style properties on the object (and nested JavaBeans). Values submitted in an HTML Form will be bound to a property on the object if such a property is defined. The ActionBeanContext is used primarily to provide access to Servlet APIs such as the request and response, and other information generated during the pre-processing of the request.
</blockquote>

<p>
In summary, it's a simple interface with a pair of methods to get and set an <code>ActionBeanContext</code> instance, which in turn provides access to other classes including the servlet request and response. This needs to be implemented by any class that would like to respond to web requests although, unlike most other webapp frameworks, this interface doesn't provide a contract for how the request will be serviced by this class. Instead, Stripes allows you to mark any arbitrary method as a request handler by using an annotation. Here, the <code>viewBlogEntries</code> method has been annotated with <code>@DefaultHandler</code>, signalling to Stripes that it's this method that should be called to process requests sent to this class. Something worth mentioning here is that more than a single method on any <code>ActionBean</code> implementation can be marked as a request handler, and this is achieved by using the <code>@HandlesEvent("...")</code> annotation (not shown here). The benefit of this approach is that it's easy to group all related request handling logic together in a single class, yet split the implementations. For example, given a form with three submit buttons, you can have one handler for all of them, or one for each. The choice is yours.
</p>

<p>
So how do requests get to this class? Well, in Stripes you map a URL to an <code>ActionBean</code> implementation using the <code>@UrlBinding(...)</code> annotation. The only other thing you need to do is declare the Stripes filter and dispatcher servlet in the <code>web.xml</code> file, as follows.
</p>

<pre class="codeSample">  &lt;filter&gt;
    &lt;display-name&gt;Stripes Filter&lt;/display-name&gt;
    &lt;filter-name&gt;StripesFilter&lt;/filter-name&gt;
    &lt;filter-class&gt;net.sourceforge.stripes.controller.StripesFilter&lt;/filter-class&gt;
  &lt;/filter&gt;

  &lt;filter-mapping&gt;
    &lt;filter-name&gt;StripesFilter&lt;/filter-name&gt;
    &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;
    &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
  &lt;/filter-mapping&gt;

  &lt;filter-mapping&gt;
    &lt;filter-name&gt;StripesFilter&lt;/filter-name&gt;
    &lt;servlet-name&gt;StripesDispatcher&lt;/servlet-name&gt;
    &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
  &lt;/filter-mapping&gt;

  &lt;servlet&gt;
    &lt;servlet-name&gt;StripesDispatcher&lt;/servlet-name&gt;
    &lt;servlet-class&gt;net.sourceforge.stripes.controller.DispatcherServlet&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;StripesDispatcher&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.action&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;</pre>

<p>
As for the actual processing, there's nothing really new here. We just find the list of blog entries and insert them into the request scope. Since we're using JSP for the view technology, we return a instance of <code>ViewResolution</code> that specifies the name of the JSP page that should be forwarded to. Other common <code>Resolution</code> implementations include <code>RedirectResolution</code> and <code>StreamingResolution</code>. As far as the JSP is concerned, it should come as no surprise that it is fairly similar to those shown before.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;${blog.name}&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;${blog.name}&lt;/h1&gt;
      &lt;h2&gt;${blog.description}&lt;/h2&gt;

      &lt;c:forEach var="blogEntry" items="${blog.blogEntries}"&gt;
        &lt;div class="blogEntry"&gt;
          &lt;h3&gt;${blogEntry.title}&lt;/h3&gt;

          &lt;c:choose&gt;
            &lt;c:when test="${not empty blogEntry.excerpt}"&gt;
              ${blogEntry.excerpt}
              &lt;p&gt;
              &lt;stripes:link href="/viewBlogEntry.action"&gt;
              Read more
              &lt;stripes:link-param name="id" value="${blogEntry.id}" /&gt;
              &lt;/stripes:link&gt;
              &lt;/p&gt;
            &lt;/c:when&gt;
            &lt;c:otherwise&gt;
              ${blogEntry.body}
            &lt;/c:otherwise&gt;
          &lt;/c:choose&gt;

          &lt;p&gt;
          Posted on &lt;fmt:formatDate value="${blogEntry.date}"
            timeZone="${blog.timeZone}" type="both"
            dateStyle="long" timeStyle="long" /&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/c:forEach&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
The only real difference between this and other JSP implementations is in the use of the <code>stripes:link</code> tag, which helps you build up hyperlinks containing parameters. Like other frameworks, this custom tag has lots of attributes mirroring those found on the HTML anchor tag, allowing you to pass through values.  You either love these tags or hate them, but it's nice to have the choice.
</p>

<p>
Before we move on, I wanted to mention that <code>ActionBean</code> instances can also be used as view helpers. The example above shows an <code>ActionBean</code> implementation mapped to a specific URL that, when requested, causes the default handler to execute and forward the user onto the appropriate JSP. As an alternative, we could call the JSP directly and use the Stripes <code>useActionBean</code> tag to tell the framework that we would like some code to be executed. You can find more details about this tag in the <a href="http://stripes.sourceforge.net/docs/current/taglib/stripes/useActionBean.html">taglib docs</a>, but essentially it creates a new instance of an <code>ActionBean</code> (specified by its <code>UrlBinding</code>), binds any parameters and then optionally calls a named handler. Take a look at the <a href="http://stripes.mc4j.org/confluence/display/stripes/Best+Practices">best practices</a> page for more information on this. Again, Stripes gives you choice.
</p>

<p>
<b>Blog entry detail page</b>
<br />
As you might expect, the blog entry page is similar. Here's the Java code that makes up the action.
</p>

<pre class="codeSample">package action;

import net.sourceforge.stripes.action.*;
import domain.BlogService;
import domain.Blog;
import domain.BlogEntry;

/**
 * A Stripes ActionBean that is responsible for allowing the user
 * to view a single blog entry.
 *
 * @author    Simon Brown
 */
@UrlBinding("/viewBlogEntry.action")
public class ViewBlogEntryActionBean implements ActionBean {

  private ActionBeanContext context;
  private String id;

  public ActionBeanContext getContext() {
    return context;
  }

  public void setContext(ActionBeanContext context) {
    this.context = context;
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  @DefaultHandler
  @DontValidate
  public Resolution viewBlogEntry() throws IOException {
    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();

    context.getRequest().setAttribute("blog", blog);

    BlogEntry blogEntry = blog.getBlogEntry(id);
    if (blogEntry == null) {
      context.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND);
      return null;
    } else {
      context.getRequest().setAttribute("blogEntry", blogEntry);
      return new ForwardResolution("/viewBlogEntry.jsp");
    }
  }

}</pre>

<p>
As with other implementations, there's a simple flow of code of that finds the blog and, if the specified blog entry is found, forwards the user to the blog entry page. However, the thing that that makes this different from many other frameworks is that any submitted request parameters are automatically mapped by Stripes onto JavaBean properties on your <code>ActionBean</code> implementation. In this case, an integer <code>id</code> property has been defined to represent the ID of the blog entry being requested, and this is available for use in the handler method.
</p>

<p>
So, moving on, you'd expect that the JSP implementation of the view blog entry page is also similar to those shown before. You'd be right, here it is.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;${blogEntry.title} : ${blog.name}&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;${blog.name}&lt;/h1&gt;
      &lt;h2&gt;${blog.description}&lt;/h2&gt;

      &lt;div class="blogEntry"&gt;
        &lt;h3&gt;${blogEntry.title}&lt;/h3&gt;

        ${blogEntry.body}

        &lt;p&gt;
        Posted on &lt;fmt:formatDate value="${blogEntry.date}"
          timeZone="${blog.timeZone}" type="both"
          dateStyle="long" timeStyle="long" /&gt;
        &lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
<b>Summary</b>
<br />
Stripes is one of a new breed of frameworks that takes advantage of the new features provided by Java 5 and this really shows. Where other frameworks adopt verbose XML files to map HTTP requests onto classes that will process them, Stripes adopts a much simpler annotation based approach, which really seems to work. Likewise, its use of returning explicit <code>Resolution</code>s is a nice change from the complexities of defining return values/views in XML. In Stripes, the easy stuff is easy. I'm looking forward to revisiting it with some read/write behaviour in the web application.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Wicket</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2006/03/comparing_webap_8.html" />
<modified>2006-03-09T09:53:26Z</modified>
<issued>2006-03-09T09:53:15Z</issued>
<id>tag:weblogs.java.net,2006:/blog/simongbrown/76.4280</id>
<created>2006-03-09T09:53:15Z</created>
<summary type="text/plain">Guillermo Castro has posted a Wicket implementation of the webapp comparison that I started a while ago. It&apos;s an interesting read and the contrast with most page/request based webapp frameworks is amazing.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
<a href="http://javageek.org/">Guillermo Castro</a> has posted <a href="http://javageek.org/2006/03/08/comparing_web_frameworks_wicket.html">a Wicket implementation</a> of the webapp comparison that I started a while ago. It's an interesting read and the contrast with most page/request based webapp frameworks is amazing. In summary, Guillermo says:
</p>

<blockquote>
Wicket, in my opinion, focuses the development efforts in the right place, inside plain Java code, and leaves the graphical presentation where it should be, inside html. At first you might find a little hard to grasp this paradigm shift, as so many developers are being 'forced' to rely on jstl and jsp scriptlets to accomplish logic programming for a page with all the other frameworks. But once you get used to this, I'm sure wicket will provide really fast development times.
</blockquote>

<p>
From my perspective, the thing that I really like about Wicket is that way that you can build common components, as illustrated by the <code>BasePage</code> class. This is a really neat way of building in commality across many pages in terms of their content and their layout. The thing I find most interesting about the Wicket implementation is summed up by the following comment that was left on Guillermo's blog.
</p>

<blockquote>
I've never seen a finer explanation of why Java web development takes forever.
</blockquote>

<p>
One of the reasons that I wanted to compare frameworks with a simple read-only app is because I wanted to see whether the easy stuff was actually easy, and I've taken a lot of flak about this. From a newcomers perspective, Wicket *looks* complicated. Once I (eventually!) get a few more frameworks written up, I'll add some read/write behaviour into the application and hopefully we'll start to see some of Wicket's strengths shine through.
</p>

<p>
My thanks go to Guillermo for volunteering to do this. I have the WebWork and Stripes versions half written up, so I'll make an effort to getting these out as soon as possible. If anybody would like to volunteer to provide a similar implementation in other webapp frameworks, please get in touch and I'll e-mail you the source. If you don't have a website/blog, I'm more than happy to publish it on my blog for you.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Struts</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2006/01/comparing_webap_7.html" />
<modified>2006-01-26T17:49:00Z</modified>
<issued>2006-01-26T17:48:52Z</issued>
<id>tag:weblogs.java.net,2006:/blog/simongbrown/76.4005</id>
<created>2006-01-26T17:48:52Z</created>
<summary type="text/plain">Struts is the grandaddy of Java webapp frameworks so it&apos;s fitting that we start our tour here. I think it&apos;s probably safe to say that Struts was the first model 2 (web MVC) framework to gain widespread adoption in the Java arena and to this day it&apos;s still used by many people.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
<a href="http://struts.apache.org">Struts</a> is the grandaddy of Java webapp frameworks so it's fitting that we start our tour here. I think it's probably safe to say that Struts was the first model 2 (web MVC) framework to gain widespread adoption in the Java arena and to this day it's still used by many people.
</p>

<p>
Just to ensure everybody is up to speed, model 2/web MVC is an architectural pattern that promotes separation of concerns between the model, the view and the controller in a web environment. As we saw in the previous model 1 implementations of the sample application, each of the JSP pages contains Java code to lookup data and display it to the user. With an MVC approach, each of the components has a strict responsibility as follows.
</p>

<ul>
<li><b>Model</b> : represents the data being viewed/manipulated.</li>
<li><b>View</b> : responsible for rendering the model back to the user.</li>
<li><b>Controller</b> : responsible for taking the request/user input and initialising the model, manipulating it, etc.</li>
</ul>

<p>
In reality, different people have different views as to whether the controller represents only the web specific parts of the process flow and whether real business logic in fact resides in the model (it being a model of the underlying business). What's important here is that web MVC promotes a separation of concerns through reusable and testable components, regardless of how you cut it. For more information about the model 2 architecture, take a look at <a href="http://www.simongbrown.com/blog/files/561x_12.pdf">Designing Web Applications and Servlet Patterns</a>.
</p>

<p>
<b>Home page</b><br />
So what's different between the Struts version of the example application and the original model 1 version? Remember that Java code at the top of the page? Basically, that's been moved into a Java class.
</p>

<pre class="codeSample">package action;

import domain.Blog;
import domain.BlogService;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ViewBlogEntriesAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) throws Exception {

    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    request.setAttribute("blog", blog);

    return mapping.findForward("success");
  }
}</pre>

<p>
In Struts terminology, this class is called an action although you'll also see this general pattern referred to as the command pattern. At runtime, the Struts controller (a Java servlet) maps the incoming request onto an action class and calls the <code>execute()</code> method, which contains the (business) logic required to service the request. In the example, this logic is responsible for locating the <code>Blog</code> instance and making it available (via the request) so that the recent list of blog entries can be presented back to the user. As with all of the others, this example uses JSP as the view technology, although you'll notice from the code above that we don't explicitly say, "please now show JSP page X". We'll cover this shortly but for now, here's the JSP page itself.

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %&gt;
&lt;%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %&gt;
&lt;%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;&lt;bean:write name="blog" property="name" /&gt;&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;&lt;bean:write name="blog" property="name" /&gt;&lt;/h1&gt;
      &lt;h2&gt;&lt;bean:write name="blog" property="description" /&gt;&lt;/h2&gt;

      &lt;logic:iterate id="blogEntry" name="blog" property="blogEntries" &gt;
        &lt;div class="blogEntry"&gt;
          &lt;h3&gt;&lt;bean:write name="blogEntry" property="title" /&gt;&lt;/h3&gt;
        &lt;/div&gt;

        &lt;logic:notEmpty name="blogEntry" property="excerpt"&gt;
          &lt;bean:write name="blogEntry" property="excerpt" filter="false" /&gt;
          &lt;p&gt;
          &lt;html:link action="viewBlogEntry" paramId="id" paramName="blogEntry" paramProperty="id"&gt;Read more&lt;/html:link&gt;
          &lt;/p&gt;
        &lt;/logic:notEmpty&gt;

        &lt;logic:empty name="blogEntry" property="excerpt"&gt;
          &lt;bean:write name="blogEntry" property="body" filter="false" /&gt;
        &lt;/logic:empty&gt;

        &lt;p&gt;
        Posted on &lt;bean:write name="blogEntry" property="date" format="dd MMM yyyy HH:mm:ss" /&gt;
        &lt;/p&gt;
      &lt;/logic:iterate&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
As you can see, moving the Java code out of the page makes for a shorter JSP that looks just like regular XHTML, albeit with a few custom tags here and there. On that note, I've chosen to use Struts tags in this version of the page purely to show something a little different to last time, but you have other alternatives including the (more feature rich) JSTL tags.
</p>

<p>
So how does a request for the home page make its way through to the <code>ViewBlogEntriesAction</code> class? Well, the main <code>index.jsp</code> page contains a simple JSP forward to <code>/viewBlogEntries.do</code>, which is subsequently mapped to the <code>ViewBlogEntriesAction</code> Java class. With Struts, there are two parts to this. First of all, the mapping between <code>*.do</code> and the Struts front controller servlet is defined in the <code>web.xml</code> file, as follows.
</p>

<pre class="codeSample">  &lt;servlet&gt;
    &lt;servlet-name&gt;action&lt;/servlet-name&gt;
    &lt;servlet-class&gt;
        org.apache.struts.action.ActionServlet
    &lt;/servlet-class&gt;
    &lt;init-param&gt;
        &lt;param-name&gt;config&lt;/param-name&gt;
        &lt;param-value&gt;
         /WEB-INF/struts-config.xml
        &lt;/param-value&gt;
    &lt;/init-param&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;action&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.do&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;</pre>

<p>
Next, the mapping between a URL and the Java class responsible for processing that request is specified in a file called <code>struts-config.xml</code> that typically resides in <code>/WEB-INF</code> (but is configurable, as you see above). Here's the relevant part of the file that illustrates these mappings (path -&gt; type) for the sample application.
</p>

<pre class="codeSample">    &lt;action-mappings&gt;

      &lt;action path="/viewBlogEntries" type="action.ViewBlogEntriesAction" name="viewBlogEntries"&gt;
        &lt;forward name="success" path="/viewBlogEntries.jsp" /&gt;
      &lt;/action&gt;

      &lt;action path="/viewBlogEntry" type="action.ViewBlogEntryAction" name="viewBlogEntry"&gt;
        &lt;forward name="success" path="/viewBlogEntry.jsp" /&gt;
        &lt;forward name="notfound" path="/404.jsp" /&gt;
      &lt;/action&gt;

    &lt;/action-mappings&gt;</pre>

<p>
Within each of the action mappings, you'll also notice one or <code>forward</code> elements and these are essentially an abstraction over the JSP that will be responsible for rendering the response. It's probably worth noting that this is just a URI, so you don't have to reference a JSP page here. If you look back to the <code>ViewBlogEntriesAction</code> class above, you'll see that the last line in the <code>execute</code> method performs <code>mapping.findForward("success")</code>. This says, please find the mapping called <code>success</code> that's defined for this action mapping and forward control to it. In this case, the <code>viewBlogEntries.jsp</code> page is used. This completes the picture and is the basic way that most requests in Struts are handled.
</p>

<p>
<b>Blog entry detail page</b><br />
Likewise, for the blog entry page we have an action class and a JSP page. Here's the action.
</p>

<pre class="codeSample">package action;

import domain.Blog;
import domain.BlogEntry;
import domain.BlogService;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ViewBlogEntryAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) throws Exception {

    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    request.setAttribute("blog", blog);

    BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
    if (blogEntry == null) {
      return mapping.findForward("notfound");
    } else {
      request.setAttribute("blogEntry", blogEntry);
      return mapping.findForward("success");
    }
  }

}</pre>

<p>
No big surprises here except that there are two possible routes through the action depending on whether the specified blog entry is found or not. And here's the JSP page used to render the successful response.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;&lt;bean:write name="blogEntry" property="title" /&gt; : &lt;bean:write name="blog" property="name" /&gt;&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;&lt;bean:write name="blog" property="name" /&gt;&lt;/h1&gt;
      &lt;h2&gt;&lt;bean:write name="blog" property="description" /&gt;&lt;/h2&gt;

      &lt;div class="blogEntry"&gt;
        &lt;h3&gt;&lt;bean:write name="blogEntry" property="title" /&gt;&lt;/h3&gt;

        &lt;bean:write name="blogEntry" property="body" filter="false" /&gt;

        &lt;p&gt;
        Posted on &lt;bean:write name="blogEntry" property="date" format="dd MMM yyyy HH:mm:ss" /&gt;
        &lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
<b>Summary</b><br />
Despite its age, Struts is still one of the mostly widely used web application frameworks and one of the top choices for teams building Java EE systems. Additionally, the overall implementation strategy (called the <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html">Command and controller strategy</a> in Java EE pattern documentation) is probably the most pervasive in both bespoke build and, as we'll be seeing, other open source alternatives to Struts.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Model 1 with JSP XML</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2006/01/comparing_webap_6.html" />
<modified>2006-01-12T10:49:22Z</modified>
<issued>2006-01-12T10:49:12Z</issued>
<id>tag:weblogs.java.net,2006:/blog/simongbrown/76.3928</id>
<created>2006-01-12T10:49:12Z</created>
<summary type="text/plain">For completeness, I wanted to show how the JSP pages from the JSTL version could be written using the JSP XML syntax.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
For completeness, I wanted to show how the JSP pages from the <a href="http://weblogs.java.net/blog/simongbrown/archive/2006/01/comparing_webap_5.html">JSTL version</a> could be written using the JSP XML syntax. Unsurprisingly, many people don't even know of its existence and, as I've <a href="http://www.simongbrown.com/blog/2005/10/14/jsp_xml_syntax.html">blogged before</a>, there aren't that many situations where you'd want to use it to write pages by hand. Should you need to, here are a couple of examples of how you would go about it using the XML syntax.
</p>

<p>
<b>Home page</b>
<br />
Here's the home page once again, implemented using the JSTL and written in the JSP XML syntax.
</p>

<pre class="codeSample">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jsp:root xmlns="http://www.w3.org/1999/xhtml"
   xmlns:jsp="http://java.sun.com/JSP/Page"
   xmlns:c="http://java.sun.com/jstl/core_rt"
   xmlns:fmt="http://java.sun.com/jstl/fmt_rt"
   version="2.0"&gt;

  &lt;jsp:useBean id="blogService" scope="request" class="domain.BlogService"/&gt;
  &lt;c:set var="blog" value="${blogService.blog}" /&gt;

  &lt;jsp:output doctype-root-element="html"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/&gt;
  &lt;jsp:directive.page contentType="text/html;charset=UTF-8" /&gt;

  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

    &lt;head&gt;
      &lt;title&gt;${blog.name}&lt;/title&gt;
      &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
    &lt;/head&gt;

    &lt;body&gt;
      &lt;div id="container"&gt;
        &lt;h1&gt;${blog.name}&lt;/h1&gt;
        &lt;h2&gt;${blog.description}&lt;/h2&gt;

        &lt;c:forEach var="blogEntry" items="${blog.blogEntries}"&gt;
          &lt;div class="blogEntry"&gt;
            &lt;h3&gt;${blogEntry.title}&lt;/h3&gt;

            &lt;c:choose&gt;
              &lt;c:when test="${not empty blogEntry.excerpt}"&gt;
                ${blogEntry.excerpt}
                &lt;p&gt;
                &lt;a href="viewBlogEntry.jsp?id=${blogEntry.id}"&gt;Read more&lt;/a&gt;
                &lt;/p&gt;
              &lt;/c:when&gt;
              &lt;c:otherwise&gt;
                ${blogEntry.body}
              &lt;/c:otherwise&gt;
            &lt;/c:choose&gt;

            &lt;p&gt;
            Posted on &lt;fmt:formatDate value="${blogEntry.date}"
                        timeZone="${blog.timeZone}" type="both"
                        dateStyle="long" timeStyle="long" /&gt;
            &lt;/p&gt;
          &lt;/div&gt;
        &lt;/c:forEach&gt;
      &lt;/div&gt;
    &lt;/body&gt;

  &lt;/html&gt;

&lt;/jsp:root&gt;</pre>

<p>
In comparison to the previous implementation, the major difference here is that the JSP page must be well formed XML, with everything wrapped up inside a <code>&lt;jsp:root&gt;</code> element. In addition, the taglib directives are replaced by a simple XML namespace, which is really quite neat.
</p>

<p>
<b>Blog entry detail page</b>
<br />
The blog entry detail page is fairly similar in all respects, with the Java code at the top of the page now being wrapped up inside a <code>&lt;jsp:scriptlet&gt;</code> element.
</p>

<pre class="codeSample">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jsp:root xmlns="http://www.w3.org/1999/xhtml"
   xmlns:jsp="http://java.sun.com/JSP/Page"
   xmlns:c="http://java.sun.com/jstl/core_rt"
   xmlns:fmt="http://java.sun.com/jstl/fmt_rt"
   version="2.0"&gt;

  &lt;jsp:output doctype-root-element="html"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/&gt;
  &lt;jsp:directive.page contentType="text/html;charset=UTF-8" /&gt;
  &lt;jsp:directive.page import="domain.*" /&gt;

  &lt;jsp:scriptlet&gt;
    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    request.setAttribute("blog", blog);

    BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
    if (blogEntry == null) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    } else {
      request.setAttribute("blogEntry", blogEntry);
    }
  &lt;/jsp:scriptlet&gt;

  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

    &lt;head&gt;
      &lt;title&gt;${blogEntry.title} : ${blog.name}&lt;/title&gt;
      &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
    &lt;/head&gt;

    &lt;body&gt;
      &lt;div id="container"&gt;
        &lt;h1&gt;${blog.name}&lt;/h1&gt;
        &lt;h2&gt;${blog.description}&lt;/h2&gt;

        &lt;div class="blogEntry"&gt;
          &lt;h3&gt;${blogEntry.title}&lt;/h3&gt;

          ${blogEntry.body}

          &lt;p&gt;
          Posted on &lt;fmt:formatDate value="${blogEntry.date}"
                      timeZone="${blog.timeZone}" type="both"
                      dateStyle="long" timeStyle="long" /&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/body&gt;

  &lt;/html&gt;

&lt;/jsp:root&gt;</pre>

<p>
<b>Summary</b>
<br />
All in all, there aren't massive changes between writing a page in the native JSP syntax and writing it in the XML syntax, but care does have to be taken to ensure that your JSP pages are valid XML and easily readable if using the latter. Personally, I've never seen the XML syntax in use on projects that I've been involved with but the choice, as they say, is yours.
</p>

<p>
Right, let's put model 1 behind us and start comparing some webapp frameworks. :-)
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Model 1 with JSTL</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2006/01/comparing_webap_5.html" />
<modified>2006-01-10T17:05:32Z</modified>
<issued>2006-01-10T17:05:24Z</issued>
<id>tag:weblogs.java.net,2006:/blog/simongbrown/76.3920</id>
<created>2006-01-10T17:05:24Z</created>
<summary type="text/plain">It&apos;s been a while since the last blog entry, but let&apos;s continue our look at the webapp frameworks with another model 1 implementation, this time using the JavaServer Pages Standard Tag Library (JSTL).</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
It's been a while since the last blog entry, but let's continue our look at the webapp frameworks with another model 1 implementation, this time using the JavaServer Pages Standard Tag Library (JSTL).
</p>

<p>
In <a href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap_4.html">Comparing webapp frameworks : Model 1 with scriptlets</a> we saw that model 1 applications typically have some boilerplate code at the top of the page to "set the scene" and the use of scriptlets means short pieces of Java code scattered throughout the page to control the presentation logic. As an alternative to this, we could use the JSTL.
</p>

<p>
<b>Home page</b>
<br />
Here's the home page, implemented using the JSTL.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;

&lt;jsp:useBean id="blogService" scope="request" class="domain.BlogService"/&gt;
&lt;c:set var="blog" value="${blogService.blog}" /&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;${blog.name}&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;${blog.name}&lt;/h1&gt;
      &lt;h2&gt;${blog.description}&lt;/h2&gt;

      &lt;c:forEach var="blogEntry" items="${blog.blogEntries}"&gt;
        &lt;div class="blogEntry"&gt;
          &lt;h3&gt;${blogEntry.title}&lt;/h3&gt;

          &lt;c:choose&gt;
            &lt;c:when test="${not empty blogEntry.excerpt}"&gt;
              ${blogEntry.excerpt}
              &lt;p&gt;
              &lt;a href="viewBlogEntry.jsp?id=${blogEntry.id}"&gt;Read more&lt;/a&gt;
              &lt;/p&gt;
            &lt;/c:when&gt;
            &lt;c:otherwise&gt;
              ${blogEntry.body}
            &lt;/c:otherwise&gt;
          &lt;/c:choose&gt;

          &lt;p&gt;
          Posted on &lt;fmt:formatDate value="${blogEntry.date}"
                      timeZone="${blog.timeZone}" type="both"
                      dateStyle="long" timeStyle="long" /&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/c:forEach&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
As you can see, the boilerplate code at the top of the page to locate the <code>Blog</code> instance has been replaced with a simple JSTL tag and access to all properties on <code>blog</code> is performed using the JSP expression language <code>${...}</code> construct, which is very succinct. In addition, the code that handles the presentation logic of iteration, conditional output and formatting has also been replaced by some JSTL tags. Line for line, this version is shorter and more readable than the previous one.
</p>

<p>
<b>Blog entry detail page</b>
<br />
The blog entry detail page also benefits from using the JSTL, although the scriptlet at the top of the page to locate the required blog entry is actually longer than before in order to make the objects available to the JSTL tags.
</p>

<pre class="codeSample">&lt;%@ page import="domain.*" %&gt;
&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;

&lt;%
  BlogService blogService = new BlogService();
  Blog blog = blogService.getBlog();
  request.setAttribute("blog", blog);

  BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
  if (blogEntry == null) {
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return;
  } else {
    request.setAttribute("blogEntry", blogEntry);
  }
%&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;${blogEntry.title} : ${blog.name}&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;${blog.name}&lt;/h1&gt;
      &lt;h2&gt;${blog.description}&lt;/h2&gt;

      &lt;div class="blogEntry"&gt;
        &lt;h3&gt;${blogEntry.title}&lt;/h3&gt;

        ${blogEntry.body}

        &lt;p&gt;
        Posted on &lt;fmt:formatDate value="${blogEntry.date}"
                    timeZone="${blog.timeZone}" type="both"
                    dateStyle="long" timeStyle="long" /&gt;
        &lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;
</pre>

<p>
<b>Summary</b>
<br />
As this example shows, the JSTL can be used to considerably reduce the need for Java code but ultimately the overall design of a model 1 page is still the same. It's hard to get away from having a block of Java code at the top of the page where processing needs to happen before the page is rendered. A good example is the blog entry detail page that looks up a blog entry given a specific ID. Next time, we'll look at a slightly different way to write the pages.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Model 1 with scriptlets</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap_4.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-11-23T19:42:13Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3694</id>
<created>2005-11-23T19:42:13Z</created>
<summary type="text/plain">Before we dive into the frameworks, I want to drop back to basics to give some context behind why the frameworks exist and what benefits they provide. For this reason, let&apos;s look at a naive model 1 implementation of the sample application. If you&apos;re already familiar with the whole model 1 vs. model 2 thing, you might want to skip reading this particular entry.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
Before we dive into the frameworks, I want to drop back to basics to give some context behind why the frameworks exist and what benefits they provide. For this reason, let's look at a naive model 1 implementation of the sample application. If you're already familiar with the whole model 1 vs. model 2 thing, you might want to skip reading this particular entry.
</p>

<p>
<b>Overview</b>
<br />
An in-depth explanation of model 1 vs. model 2 can be found in <a href="http://www.simongbrown.com/blog/files/561x_12.pdf">Designing Web Applications and Servlet Patterns</a>, but essentially a model 1 web application architecture is where all of your logic is wrapped up inside the pages of your application. By logic, I'm referring to things like business logic, presentation logic and page flow. Let's take a look at some examples of this by seeing how a model 1 version of the sample application might be built.
</p>

<p>
<b>Home page</b>
<br />
From a JSP perspective, a model 1 web application is very easy to build because you just start coding away in your JSP pages. Here's what the home page looks like when implemented using a model 1 architecture.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ page import="domain.*,
                 java.util.Iterator,
                 java.text.DateFormat" %&gt;
&lt;%
  BlogService blogService = new BlogService();
  Blog blog = blogService.getBlog();
%&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;&lt;%= blog.getName() %&gt;&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;&lt;%= blog.getName() %&gt;&lt;/h1&gt;
      &lt;h2&gt;&lt;%= blog.getDescription() %&gt;&lt;/h2&gt;

      &lt;%
        Iterator it = blog.getBlogEntries().iterator();
        while (it.hasNext()) {
          BlogEntry blogEntry = (BlogEntry)it.next();
      %&gt;
        &lt;div class="blogEntry"&gt;
          &lt;h3&gt;&lt;%= blogEntry.getTitle() %&gt;&lt;/h3&gt;

          &lt;%
            if (blogEntry.getExcerpt() != null) {
          %&gt;
            &lt;%= blogEntry.getExcerpt() %&gt;
            &lt;p&gt;
            &lt;a href="viewBlogEntry.jsp?id=&lt;%= blogEntry.getId()%&gt;"&gt;Read more&lt;/a&gt;
            &lt;/p&gt;
          &lt;%
            } else {
          %&gt;
            &lt;%= blogEntry.getBody() %&gt;
          &lt;%
            }
          %&gt;

          &lt;p&gt;
          &lt;%
            DateFormat dateFormat = DateFormat.getDateTimeInstance(
              DateFormat.LONG, DateFormat.LONG, blog.getLocale());
            dateFormat.setTimeZone(blog.getTimeZone());
          %&gt;
          Posted on &lt;%= dateFormat.format(blogEntry.getDate()) %&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;%
        }
      %&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
I'm not going to explain each and every line, but the basic structure breaks down as follows.
</p>

<ol>
<li>Define page characteristics and import Java classes.</li>
<li>Locate the <code>Blog</code> instance to work with, via the <code>BlogService</code>.</li>
<li>Write out the page header, title, etc.</li>
<li>For each blog entry, write out the appropriate properties.</li>
<li>Close all the tags.</li>
</ol>

<p>
For the "read more" link, this is simply implemented as a call to the blog entry detail JSP page, passing the blog entry ID as a parameter. Notice how this is conditionally included, depending on whether the excerpt is null - it's a good example of the simple presentation logic that you'll find in many web applications. The date formatting code is another example.
</p>

<p>
<b>Blog entry detail page</b>
<br />
The blog entry detail page is very similar.
</p>

<pre class="codeSample">&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ page import="domain.*,
                 java.text.DateFormat" %&gt;
&lt;%
  BlogService blogService = new BlogService();
  Blog blog = blogService.getBlog();
  BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
  if (blogEntry == null) {
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return;
  }
%&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

  &lt;head&gt;
    &lt;title&gt;&lt;%= blogEntry.getTitle() %&gt; : &lt;%= blog.getName() %&gt;&lt;/title&gt;
    &lt;link rel="stylesheet" href="screen.css" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id="container"&gt;
      &lt;h1&gt;&lt;%= blog.getName() %&gt;&lt;/h1&gt;
      &lt;h2&gt;&lt;%= blog.getDescription() %&gt;&lt;/h2&gt;

      &lt;div class="blogEntry"&gt;
        &lt;h3&gt;&lt;%= blogEntry.getTitle() %&gt;&lt;/h3&gt;

        &lt;%= blogEntry.getBody() %&gt;

        &lt;p&gt;
        &lt;%
          DateFormat dateFormat = DateFormat.getDateTimeInstance(
            DateFormat.LONG, DateFormat.LONG, blog.getLocale());
          dateFormat.setTimeZone(blog.getTimeZone());
        %&gt;
        Posted on &lt;%= dateFormat.format(blogEntry.getDate()) %&gt;
        &lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>
The scriptlet at the top of the page is probably the most interesting because that piece of code is responsible for locating the requested blog entry or sending the user off to an error page, which is simply configured through the <code>web.xml</code> file with the following XML fragment.
</p>

<pre class="codeSample">&lt;error-page&gt;
  &lt;error-code&gt;404&lt;/error-code&gt;
  &lt;location&gt;/404.jsp&lt;/location&gt;
&lt;/error-page&gt;</pre>

<p>
<b>Summary</b>
<br />
Both pages contain a short piece of Java code at the top of the page to "set the scene". This type of logic is typically what you find scattered throughout the pages of a model 1 webapp, the downsides of which include reduced maintainability, reusability and testability. Both additionally contain several other short pieces of Java code to handle some presentation logic such as iteration, conditional processing and date formatting. As we'll see next, the JSP Standard Tag Library (JSTL) can help to solve at least some of these problems.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Domain model</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap_3.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-11-09T12:21:22Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3591</id>
<created>2005-11-09T12:21:22Z</created>
<summary type="text/plain">Before we kick off our look at webapp frameworks, let&apos;s establish the domain model we&apos;re working with.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
Before we kick off our look at webapp frameworks, let's establish the domain model we're working with. It's pretty simple - blogs and blog entries, residing in a package called <code>domain</code>.
</p>

<p>
<div align="center">
<img src="http://www.simongbrown.com/blog/images/2005/comparing-webapps4.png" alt="Domain model : BlogService, Blog and BlogEntry" />
</div>
</p>

<p>
Because I want to concentrate on the presentation aspects of the frameworks this time around, I'm ignoring the persistence mechanism. Instead, I'm just assuming that data access will be achieved via a "service", regardless of whether it uses direct JDBC, a DAO, a web service, Hibernate, etc.
</p>

<p>
So that's the model. The question is, will any of the frameworks or view technologies require us to change it?
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Requirements</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap_1.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-11-04T13:45:14Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3547</id>
<created>2005-11-04T13:45:14Z</created>
<summary type="text/plain">So, to compare webapp frameworks we need an example web application.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
So, to compare webapp frameworks we need an example web application. I've chosen to build a simple blog. Here are the functional requirements.
</p>

<ol>
<li>The home page will display a list of the 3 most recent blog entries, in reverse chronological order. The following information will be displayed for each blog entry.</li>
<ul>
<li>Title</li>
<li>If an excerpt is present, the excerpt will be displayed with a "read more" link to the full blog entry.</li>
<li>If no excerpt is present, the full body will be displayed.</li>
<li>Date/time</li>
</ul>
<li>When a "read more" link is clicked, the resulting page will display the following information about the selected blog entry.</li>
<ul>
<li>Title</li>
<li>Body</li>
<li>Date/time</li>
</ul>
</ol>

<p>
And here are some non-functional requirements, just to make things a little more interesting.
</p>

<ol>
<li>The web application will make use of and validate against the following standards.</li>
<ul>
<li>XHTML 1.0 Transitional</li>
</ul>
<li>HTTP status codes will be used where appropriate (e.g. 404 for page not found).</li>
<li>UTF-8 will be used as the character encoding to support international character sets.</li>
<li>Dates and times will be formatted appropriately for the locale of the owning blog.</li>
<li>Dates and times will be presented in the time zone of the blog.</li>
<li>A strict MVC architecture will be adopted, with all access to views being made through the controller.</li>
<li>The technology constraints are as follows.</li>
<ul>
<li>Java SE 5.0</li>
<li>Servlet 2.4 and JSP 2.0</li>
<li>Tomcat 5.5.x</li>
</ul>
</ol>

<p>
Here are some screenshots to show what this all looks like.
</p>

<p>
<div align="center">
<img src="http://www.simongbrown.com/blog/images/2005/comparing-webapps1.jpg" alt="Home page" />
<br />
<b>Figure 1 : Home page.</b>
</div>
</p>

<p>
<div align="center">
<img src="http://www.simongbrown.com/blog/images/2005/comparing-webapps2.jpg" alt="Blog entry detail page" />
<br />
<b>Figure 2 : Blog entry detail page.</b>
</div>
</p>

<p>
<div align="center">
<img src="http://www.simongbrown.com/blog/images/2005/comparing-webapps3.jpg" alt="Page not found page" />
<br />
<b>Figure 3 : Page not found page.</b>
</div>
</p>

<p>
As I've said before, I hoping to make this an iterative process and there's plenty of scope for adding some interactivity into the example application. Next up is a look at the domain model.
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Why?</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap_2.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-11-03T19:59:54Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3544</id>
<created>2005-11-03T19:59:54Z</created>
<summary type="text/plain">&quot;Imho this is a complete waste of time and it will be another biased comparison without any real use whatshowever.&quot; So, why am I doing this?</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
After posting <a href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap.html">Comparing webapp frameworks : Introduction</a> yesterday, I got lots of feedback - some good, some bad. So, why am I doing this?
</p>

<p>
First off, here are some of the negative comments.
</p>

<ul>
<li>Imho this is a complete waste of time and it will be another biased comparison without any real use whatshowever. Please spend your time on something useful and don't add another confusing hyped comparison to the mix.</li>
<li>A propos, the easy 80% is rarely the problem and often very repetitive. Most of it is even getting totally automated with CRUD frameworks. The interesting bit is the difficult 20%, this is where the actual difficulties lie and where most time is spent.</li>
<li> No one cares about how each framework handles simple things.</li>
<li>If I wanted to compare frameworls your way I'd visit every one of the frameworks web sites...</li>
<li>Many frameworks sell there idea demonstrating how easy it is to do simple stupid examples.</li>
</ul>

<p>
Fantastic! At least people are talking and I got some response. Great to see that the community is alive. :-)
</p>

<p>
<b>Choice</b>
<br />
When choosing a platform to build a web application, J2EE is still the first choice for many. As we're all well aware, new webapp frameworks are released fairly often and I believe that there's <i>still</i> a lot of room for innovation, particularly when you look "Beyond Java", with stuff like Ruby on Rails. So, from this perspective, one of the reasons that I'm doing this is to provide an "at a glance" view of many frameworks as opposed to going in deep on a few. After all, I want to be in a position to answer questions like, "do you think we should use Struts or something newer like Stripes?". I suspect that most people would comment that both are webapp frameworks, but recommend Struts because it's proven. I could be wrong, but I do think that even an "at a glance" view offers something of value.
</p>

<p>
<b>Nobody cares about the simple stuff</b>
<br />
Taking on the comment about the 80% being easy and repetitive - yes, that's exactly what I was getting at. It <i>is</i> easy, or at least it <i>should</i> be. That's something else that I want to look into. If a particular framework makes the easy stuff hard, I'm not going to recommend it to my clients. Where's the productivity gain in slowing 80% down but making 20% really fast? True, some of the easy stuff can be automated with CRUD style webapp frameworks, but this isn't necessarily the world we live in. Just taking an example, one of my current clients is building a web presence over the top of a service oriented architecture, which is deployed on an enterprise service bus. How do those CRUD frameworks help me here?
</p>

<p>
<b>Consistency and reduced learning curve</b>
<br />
Why should I have to compare frameworks by visiting each and every website? They all differ in terms of content, layout, documentation, examples, etc. By implementing even a simple application, I can reduce the learning curve for those people that just want to quickly skim the frameworks and pick up the main points. This is made even easier if the code for the same application is available for multiple frameworks.
</p>

<p>
The other thing to pick up on here is that some of the framework sites do have incredibly simple examples. They're even simpler than the application I've come up with and that's a problem. Once you stray outside of the simple example you have to start digging around the docs. If I can at least go slightly deeper than the very simple examples, again, I think this adds value.
</p>

<p>
<b>The evolution of web MVC</b>
<br />
Another reason for doing this is to see how the web MVC pattern has evolved over the past few years. I don't want to jump ahead too much, but there are some very interesting and unique ways that this seemingly simple pattern has been implemented. I want to compare and contrast this too. Coupled with the view technologies, I want to see how these various choices affect what is ultimately the core architecture of your web application.
</p>

<p>
Just to clarify, my sample application is read-only from the perspective of the <i>user</i>. The content is dynamic, but the user can't update it. As I said, I <i>am</i> hoping to make this an iterative process and revisit it to add further levels of detail. I've got to start somewhere though. ;-)
</p>]]>

</content>
</entry>
<entry>
<title>Comparing webapp frameworks : Introduction</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/11/comparing_webap.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-11-02T20:21:32Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3534</id>
<created>2005-11-02T20:21:32Z</created>
<summary type="text/plain">Struts, WebWork, Stripes, Spring MVC, Wicket, Tapestry, JSF, etc, or even rolling your own. With so many J2EE web application frameworks to choose from, how do you decide which one to use?</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
Struts, WebWork, Stripes, Spring MVC, Wicket, Tapestry, JSF, etc, or even <a href="http://www.simongbrown.com/blog/2005/10/17/rolling_your_own.html">rolling your own</a>. With so many J2EE web application frameworks to choose from, how do you decide which one to use? Several articles (e.g. <a href="http://www.theserverside.com/articles/article.tss?l=JSFTapestry">JavaServer Faces vs Tapestry</a>) and presentations (e.g. <a href="https://equinox.dev.java.net/framework-comparison/WebFrameworks.pdf">Comparing Web Frameworks</a>) already exist, but they generally concentrate on a small subset of the available frameworks.
</p>

<p>
Over the next few weeks, I'm going to implement a small web application using as many J2EE web application frameworks that I can get my hands on. I'll be using the resulting code to compare and contrast what the frameworks provide and how they work.
</p>

<p>
Clearly this is a massive task so, to reduce the scope, I'm going to focus on what it takes to build a read only web application. If I were to hazard a guess, I'd say that the 80-20 rule applies. 80% of a web application is read only and 20% is interactive (e.g. HTML forms, AJAX, etc). Of course, this is changing with technologies like AJAX, but we're still on the upward curve. Traditionally, that 20% is the most complex and is an area where many web application frameworks claim their unique selling points. For this reason, I may iterate over the evaluation process to take into account how the frameworks help web developers build interactive webapps. For now, I'm going to look at whether the frameworks make doing the 80% easy.
</p>

<p>
In addition to looking at the webapp frameworks, I'm also going to compare and contrast some of the view technologies that are currently available. Here, I'm talking about JSP (normal and XML formats), Velocity, FreeMarker, etc. I think this adds an interesting twist and your choice of view technology may have an impact on your framework decision.
</p>

<p>
Stay tuned, it should be an interesting journey!
</p>]]>

</content>
</entry>
<entry>
<title>The Java Posse podcast</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/09/the_java_posse_1.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-09-26T13:40:10Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3316</id>
<created>2005-09-26T13:40:10Z</created>
<summary type="text/plain">After I wrote about the JavaCast being discontinued, Dick Wall got in contact to tell me about a new Java podcast that he was putting together.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>Community: Global Education and Learning Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
After I wrote about the <a href="http://weblogs.java.net/blog/simongbrown/archive/2005/09/the_javacast.html">JavaCast being discontinued</a>, <a href="http://www.voiceoftheresistance.com/">Dick Wall</a> got in contact to tell me about a new Java podcast that he was putting together with a couple of other people - Tor Norbye and Carl Quinn. This is excellent news and an <a href="http://javaposse.com/index.php?post_id=22795">initial podcast has been released</a>, featuring an interview with Rob Hardwood from JetBrains.
</p>

<p>
As of today, I noticed that you can <a href="https://phobos.apple.com/WebObjects/MZFinance.woa/wa/subscribePodcast?id=81157308">subscribe to The Java Posse via iTunes</a>. Sounds like Dick and posse have some great things in store for the new podcast so time to get subscribed and stay tuned!
</p>]]>

</content>
</entry>
<entry>
<title>The JavaCast</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/09/the_javacast.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-09-19T23:04:08Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.3284</id>
<created>2005-09-19T23:04:08Z</created>
<summary type="text/plain">Having just come back from holiday, I fired up iTunes hoping to get a new JavaCast that I could listen to on the way to work. Unfortunately, this wasn&apos;t going to be the case.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>Community: Global Education and Learning Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
Having just come back from holiday, I fired up iTunes hoping to get a new JavaCast that I could listen to on the way to work. If you've not heard of it before, the JavaCast was a podcast dedicated to news and views within the Java industry. I say "was" because after only a few episodes, <a href="http://www.voiceoftheresistance.com/?p=59">the JavaCast has been discontinued</a>. On the whole the JavaCast was pretty good. Released on a weekly basis, it had a good overview of the major news stories for the week, some of which I'd read about and some which I hadn't. The interviews were good too, with the Bruce Tate one providing some interesting insight into lightweight development techniques. My only real negatives are that it was sometimes a bit ranty and the podcasts tended to be on the long side - I think an hour is too long for a podcast.
<p>

<p>
Anyway, hopefully something similar will be revived soon, but this got me thinking. Putting together a podcast is a lot of work for one or two people and I wonder whether an open source contributor style model could be applied successfully here, helping to share out the load. A podcast by the community for the community. Perhaps a java.net podcast?
</p>]]>

</content>
</entry>
<entry>
<title>I have Servlets</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/07/i_have_servlets.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-07-15T05:07:30Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.2933</id>
<created>2005-07-15T05:07:30Z</created>
<summary type="text/plain">In &quot;Got Servlets?&quot;, Greg is asking what we&apos;d like to see in the next major revision of the Java Servlets specification. In no particular order, here are my initial thoughts.</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2EE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
In <a href="http://weblogs.java.net/blog/gmurray71/archive/2005/07/got_servlets.html">Got Servlets?</a>, Greg is asking what we'd like to see in the next major revision of the Java Servlets specification. In no particular order, here are my initial thoughts.
</p>

<ul>
<li><b>Programmatic access to the security realm</b> : There are more and more sites out there that offer users a way to sign up for their services and this is fairly tricky to do with the standard, declarative J2EE security model. If you know that you're using a particular platform (e.g. Tomcat), then you can write some code that takes advantage of the underlying way in which the security credentials are stored, and edit them appropriately. But what about when you're targeting more than a single application server platform? What about when your team is developing on Tomcat and deploying to WebLogic? In this situation, being able to access an abstraction of the underlying realm implementation would be very useful. Self registration then becomes much easier - create a principal, assign some roles and write it back to the underlying realm in a platform independent way. Yes, you can do this with external security frameworks, but it would be nice to have this as a part of the standard.</li>
<li><b>Programmatic access to the security constraints</b> : Following on from the point above, programmatic access to the security constraints of the current web application would also be really useful. Self registration on it's own lets you build applications where the content presented to the user varies based upon who that user is. However, what you can't really do is change the security constraints of the web application on the fly. For example, imagine you're a blog hosting provider. You might want to let users self register for a public blog. On the other hand, you might want to let them register for a private blog, secured by the declarative security constraints in the web.xml file. Given the choice of using filters or security constraints in the web.xml file to permit or disallow access, I'd rather use the declarative approach because it's tried and tested code, reducing the risk that my site will be breached. This is one of the major benefits of using declarative security - the container does this work for you. Again, stopping people reinventing the wheel each time the security system doesn't work for them would be nice.</li>
<li><b>Specification ambiguities</b> : Inconsistency through ambiguity is a major headache for many developers, although I'd say that it's an even bigger headache for people wanting to build J2EE applications that really can run anywhere. Take <a href="http://weblogs.java.net/pub/wlg/726">Inconsistency between Servlet specification implementations</a> as an example. Some containers provide you information about whether a user is logged in and some don't. Things like this really do need to be addressed. At the heart of this problem are ambiguities in the specification, but I'd say that the test cases around specification compliance need to be greatly improved. After all, what's the point of having a bunch of "J2EE compatible" application servers if they are inconsistent in how they implement the specs. Greatly reduces the benefit of the certification, don't you think?</li>
<li><b>Regex URL patterns</b> : The current wildcard scheme for specifying "url-pattern"s is far too limiting. Regex support would be nice, particularly now since newer versions of the J2EE spec mandate the use of versions of J2SE that contain regex support.</li>
</ul>

<p>
On a more general note, admittedly I've not used Java 5 annotations much, but I'm one of these people that is a little bit skeptical of them. They do have their uses, but I am a little concerned about them being overused, for example, to configure components through the code. Mike Spille has a great blog entry named <a href="http://www.pyrasun.com/mike/mt/archives/2005/07/13/21.45.29/index.html">Action Hippo Rangers!</a> where he talks about the ping pong nature of software development. One of the examples he cites is the adoption of annotations versus XML configuration. The point is, just because XML configuration is seen as complex and verbose, this doesn't mean that we should switch everything over to annotations. Everything in moderation, otherwise we'll be campaigning for the return of the web.xml file in a couple of years! ;-)
</p>]]>

</content>
</entry>
<entry>
<title>J2SE 5.0 updates</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/simongbrown/archive/2005/05/j2se_50_updates_1.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-05-04T14:57:22Z</issued>
<id>tag:weblogs.java.net,2005:/blog/simongbrown/76.2392</id>
<created>2005-05-04T14:57:22Z</created>
<summary type="text/plain">Why aren&apos;t all J2SE 5.0 updates going to make it onto the java.com website?</summary>
<author>
<name>simongbrown</name>

<email>simon@javaranch.com</email>
</author>
<dc:subject>J2SE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/simongbrown/">
<![CDATA[<p>
This blog entry should really be titled, "J2SE 5.0 updates, or the lack of them". I've read <a href="http://weblogs.java.net/blog/kgh/archive/2005/04/j2se_50_update.html">Graham's blog entry</a> about J2SE 5.0 updates a couple of times now and I still don't understand why you wouldn't want to push out minor updates via the consumer java.com website. The end result of this is that J2SE 5.0 Update 2 is available from java.com, while Update 3 is available from the <a href="http://java.sun.com/j2se/1.5.0/download.jsp">java.sun.com</a> website.
</p>

<p>
I <i>can</i> see why this may be simpler for end-users, but not for anybody else. Think about it. You're supporting an application and a user encounters a bug that you don't see on your computer with the JDK installed. A response of "make sure your JRE is up-to-date" just isn't going to cut it anymore. As far as the end-user is concerned, their JRE <i>is</i> up-to-date. Unfortunately we know better. Of course, we could point them at the java.sun.com website, but then that defeats the purpose of the user-friendly java.com website.
</p>

<p>
Anyway, putting the inconsistency issues between java.sun.com and java.com to one side (there are a lot of very good responses to Graham's blog entry), what happens when Apple starts delivering J2SE 5.0 through the Mac OS X Software Update channel? This is the primary mechanism to ensure that end-users (and developers!) have the most up-to-date version of the Java runtime. If Apple make Update 3 available via Software Update, for once, Mac users will have a more up-to-date version of the runtime than those running Windows!  Well, until Mustang is released anyway.
</p>

<p>
I just don't get it. The Java runtime version numbering is confusing enough as it is. Take a look at the java.com website, even that refers to "JRE 1.5.0" rather than "J2SE 5.0". Complicate matters further by not ensuring that everybody is in step and we've got a real problem on our hands. No wonder Java is struggling to gain ground on the desktop. Sun, please revisit this decision and let us have the same version of "Java everywhere".
</p>]]>

</content>
</entry>

</feed>