Search |
||
Comparing webapp frameworks : StripesPosted by simongbrown on March 10, 2006 at 6:06 AM PST
Stripes 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.
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
Home page
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");
}
}
First up, we need to implement an interface called 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.
In summary, it's a simple interface with a pair of methods to get and set an
So how do requests get to this class? Well, in Stripes you map a URL to an <filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>StripesDispatcher</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>net.sourceforge.stripes.controller.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
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 <%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>${blog.name}</title>
<link rel="stylesheet" href="screen.css" type="text/css" />
</head>
<body>
<div id="container">
<h1>${blog.name}</h1>
<h2>${blog.description}</h2>
<c:forEach var="blogEntry" items="${blog.blogEntries}">
<div class="blogEntry">
<h3>${blogEntry.title}</h3>
<c:choose>
<c:when test="${not empty blogEntry.excerpt}">
${blogEntry.excerpt}
<p>
<stripes:link href="/viewBlogEntry.action">
Read more
<stripes:link-param name="id" value="${blogEntry.id}" />
</stripes:link>
</p>
</c:when>
<c:otherwise>
${blogEntry.body}
</c:otherwise>
</c:choose>
<p>
Posted on <fmt:formatDate value="${blogEntry.date}"
timeZone="${blog.timeZone}" type="both"
dateStyle="long" timeStyle="long" />
</p>
</div>
</c:forEach>
</div>
</body>
</html>
The only real difference between this and other JSP implementations is in the use of the
Before we move on, I wanted to mention that
Blog entry detail page
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");
}
}
}
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 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. <%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>${blogEntry.title} : ${blog.name}</title>
<link rel="stylesheet" href="screen.css" type="text/css" />
</head>
<body>
<div id="container">
<h1>${blog.name}</h1>
<h2>${blog.description}</h2>
<div class="blogEntry">
<h3>${blogEntry.title}</h3>
${blogEntry.body}
<p>
Posted on <fmt:formatDate value="${blogEntry.date}"
timeZone="${blog.timeZone}" type="both"
dateStyle="long" timeStyle="long" />
</p>
</div>
</div>
</body>
</html>
Summary
»
Comments
Comments are listed in date ascending order (oldest first)
|
||
|
|