Stripes: A Successful First Project

Posted on by in Web

We’re wrapping up a project that I’ve been leading since September and I’ve been reflecting on some of my decisions. Some of this reflection might be interesting to other developers. There are a few things on my mind, but I’ll start off off with my decision to use Stripes as our MVC instead of our usual, Spring MVC.

Background

I’ve never been completely satisfied with Spring MVC (note that it’s pretty hard to win me over completely). We know it well and we’ve had many successful projects while using it. We’ve also used many of the new features that came along with Spring 2.5 (@Controller, more convention over configuration, etc), but in the end I still wasn’t loving it.

I came across Stripes over a year ago, and noted that it had a small but fairly vibrant and excited community. The projects goals definitely resonated with me:

  • Make developing web applications in Java easy
  • Provide simple yet powerful solutions to common problems
  • Make the Stripes ramp up time for a new developer less than 30 minutes
  • Make it really easy to extend Stripes, without making you configure every last thing

So I decided to give it a try on a real project. Switching from something we know inside and out to something that none of us had production experience with was arguably risky, so we decided to give it a try for a week with the intention that we’d go back to Spring MVC if anything took too long or felt awkward. Thankfully, that never happened.

Some of this article may read a bit like a Stripes versus Spring MVC comparison. That’s not really my intention, but it’s somewhat inevitable as much of my experience has been with Spring MVC. This isn’t intended to be a Stripes tutorial (there are great ones out there), so the code snippets and technical details will be sparse.

Controller Lifecycle, Binding, and the Model

Stripes controllers are called “Actions” or “ActionBeans” and each incoming HTTP request is routed to one primary Action (like Spring MVC). Stripes creates a new Action instance for each incoming request; Spring Controllers are singletons in comparison. Stripes binds parameters into the fields on the Action where Spring MVC passes them as method parameters. The Stripes Action is not only the “Controller” in the MVC, but it also serves as the root of the “Model” as well. The Action is made available to the View and all properties with getters can be queried using JSP-EL. Spring’s model is separate, necessitated by the Singleton nature of the Controller.

Let’s look at a simple example:

// URI and embedded parameters defined using CleanURLs
@UrlBinding("/status/{orderId}/{$event}")
public class OrderStatusAction extends AbstractActionBean
{
    // Spring managed service to be dependency injected (see "Worth Mentioning" below)
    @Autowired OrderService orderService;

    // Required incoming parameter bound in the URI with {orderId}
    @Validate(required = true, minvalue = 1) long orderId;

    // OrderStatus to be accessible from the view for rendering
    OrderStatus orderStatus;

    // public setter tells stripes to allow binding
    public void setOrderId(long orderId) { this.orderId = orderId; }

    // public getter tell stripes to allow access from the view
    public OrderStatus getOrderStatus() { return orderStatus; }

    public Resolution view()
    {
        orderStatus = orderService.getOrderStatus(orderId);
        if (orderStatus == null) return new ErrorResolution(404);
        return new ForwardResolution("/WEB-INF/jsp/order-status.jsp");
    }
}

In our view we can access the Action / Model:

...
<jsp:useBean id="actionBean" scope="request" type="eg.OrderStatusBean"/>
...
<li>Order Number: ${actionBean.orderStatus.order.id}</li>
<li>Status: ${actionBean.orderStatus.status}</li>
<li>Tracking Number: ${actionBean.orderStatus.trackingNumber}</li>
...

This example binds to a long, which is pretty simple. Stripes can bind into graphs of objects, instantiating them along the way if necessary. Collections are fully supported as well. We haven’t yet found an example of something we couldn’t bind into right out of the box.

While I first was resistant to the Stripes lifecycle and combination of Controller and Model, I soon warmed up to it and now I find it quite natural, a bit better from a code readability standpoint, and more aesthetic. It’s just the right amount of abstraction and encapsulation to make for speedy development while being easy to maintain. I really like the fact that new instances of actions are created for each request, because the alternative is to pass all of your state into a handler method, which can easily lead hard-to-read code, especially with the annotations required to describe which request parameter maps to which method parameter.

If you can’t bind directly into your value objects and entities, the Action gives you a great place to bind into first, allowing you to manually instantiate your domain objects plugging in values from the Action. This is quite useful when your domain model isn’t direct-binding friendly because of invariant enforcing, immutable value objects, and other practices encouraged by Domain Driven Design.

We keep our Actions simple and lightweight, deferring all non-display logic to transactional, spring-managed services. I’ve seen examples where Actions are directly interacting with the database, a pattern I discourage.

If you want to know more about how Stripes works, check out the references section at the end of this article.

Generating URIs in Views

I can’t tell you how many times I’ve run into regressions after making changes to URIs where a page would link to a controller at the wrong URI. With Stripes, your URIs are defined once and only once, so when you change where an Action lives, pages will link to it correctly at its new location. Stripes tags take a beanclass argument so that it can determine the correct URI at runtime rather than hard-coding it in the view.

<stripes:link beanclass="eg.OrderStatusAction" event="view">
  <stripes:param name="orderId" value="65432"/>
  View Order Status
</stripes:link>

Renders: <a href="http://example.com/status/65432/view">View Order Status</a>

The <stripes:url …/> and <stripes:form …/> tags work the same way. To round it out, Actions can forward or redirect to other Actions without embedding URIs:

return new ForwardResolution(OrderHistoryAction.class, &quot;view&quot;).
return new RedirectResolution(OrderHistoryAction.class, &quot;view&quot;).

The net result is that there’s a single definition of each URI in our system and it lives on the Action which handles that URI, realizing the Don’t Repeat Yourself (DRY) principle. We’ve been able able to change our URIs easily without fear of breaking views, which has been helpful as the project grows.

Configuration

Stripes only needs a few lines of configuration in your web.xml. That’s it (really). Stripes was built with convention over configuration in mind from day one. Actions and Extensions (Converters, Formatters, Interceptors, etc) are auto-discovered via classpath scanning. We never found ourselves needing to configure something differently than how it was out of the box.

While you can configure Spring MVC to be convention based (it’s okay to chuckle at this too), it’s not that way out of the box. Perhaps Spring 3.0 will change this, but I have the sense that no matter what, there will always be some evidence of the fact that Spring MVC’s internals allow a wide range of configuration.

Converters and Formatters

In other frameworks, these concepts are often conflated into a single class. Stripes converters do one thing: convert from strings to objects (e.g. phone numbers, zip codes, etc). Whenever you need to turn an incoming request parameters into something more than a string, the converter is there to help.

Formatters work the other way, formatting objects into something that looks right on the screen as text. Formatters can support multiple format types, so that you can support displaying objects differently when necessary (e.g. phone with extension, zip code with a plus 4, etc).

These helpers are simple to write and test. All of the stripes tags will use them if they’re present, so it’s easy to affect how something — phone numbers for example — are displayed across the entire application.

Testing

There’s no reference to the servlet API in your Action classes, so it’s easy to write tests against the Java code within. Tests fall into two categories: very lightweight unit tests which only test what’s happening in your handler and slightly more heavy-weight tests which involve more of the stack (but not the servlet container).

The outline for a unit test goes something like this:

  1. Instantiate your Action
  2. Inject service stubs/mocks
  3. Use the public setters to specify values to necessary fields
  4. Invoke the handler
  5. Assert on the Resolution and the state of the Action (optionally your Stub)

Note that all of our Action tests fall into this category, even though you can test more of the stack (URL binding and validation).

What you can’t do — I haven’t seen any Java MVC provide this though — is write tests against the rendered markup of your views (a la Rails) without bringing up the servlet container.

Read more about testing with Stripes here.

Documentation and Community

The Stripes documentation is definitely not very complete or polished. Some of the documentation is out of date or non-existent (e.g. CleanURLs). The same goes for the examples. There is a decent book from Pragmatic Programmers press however, which I recommend if you’re interested in Stripes.

The good news is that despite all of this, it’s easy enough to find or figure out what you need without too much fuss. Piecing together examples, tutorials, bogs, documentation, etc ultimately gives you what you need. The Stripes source is small enough that you can rummage through to see how things work easily. It’s not as configurable as Spring MVC so the code is less abstract and a little easier to grok (though it’s not as elegant).

There is an active mailing list where the developers and other users help out with questions.

Conclusion

I think working with Stripes is a lot of fun and that we made the right decision to use it. I’d go as far as saying that we were at least as productive with it as we would have been with Spring MVC, and it’s likely we were more productive. I’d say that the authors have largely delivered on their goals. One of our front-end developers quickly dove right into building Actions without much help from other developers. While we had the occasional “Huh?!” moment while trying to figure out why something wasn’t working, they were few and far between.

In comparing it to Spring MVC, I think there’s a simplicity and elegance to Stripes that comes from it being just an MVC and it not having the same legacy as Spring. While Spring MVC has certainly evolved, it’s brought some of its crufty parts along with it. I’ll be keeping an eye on Spring MVC to see what’s in store with 3.0, and I hope to be proven wrong.

There’s no doubt that Stripes is in a niche as compared to many of the other web frameworks. The community is much smaller, and the development cycle much longer (last release was August 2008 and the one before that May 2007), which sometimes makes me wonder what Stripes future holds.

I’d say that one downside to Stripes, or any other framework that has a single backing Action per URI, is that there isn’t a great story for dealing with pages that aggregate a number of features and those features also show up on other pages. The problem is that we can’t rely on the Action to provide all of the reference data, so we have to rely on other mechanisms for fetching it (filters, interceptors, tags, etc). It’s not an issue with Stripes specifically, but all framework with the same approach.

For projects where this single primary controller per URI limitation isn’t a problem, I would definitely use Stripes again and I think it’s a framework Java developers should look into if they aren’t completely happy with whatever they’re using.

Also Worth Mentioning…

There are lots of other neat features in Stripes too: validation annotations and helper methods, stripes layout, flash scope, wizard forms, encrypted parameters, a JavaScriptResolution for serializing Java objects to JavaScript, etc. Open up the Stripes jar and start looking around.

Our application is using Spring as an IoC container for everything behind our Actions; to get handles to your Spring managed services we use a simple Stripes Interceptor which injects dependencies into Actions.

When using CleanURLs, you’ll want to use the DynamicMappingFilter, though there’s not much mention of it in the documentation. CleanURLs in Stripes 1.5.1 should be even more flexible (see STS-617).

We used Spring Security on our application found that Stripes and Spring Security play nicely together.

Spring 3.0 will include a few new features that are similar to features I really like in Stripes, including RESTy URLs, and tags for generating the URIs to controllers. The downside is that it’s still using the singleton model, which equates to controller handler methods with potentially lots of annotated parameters.

References

Updates: added reference to recently published Spring 3.0 MVC blog.


Feedback

  Comments: 11


  1. Good article Christian–thanks for posting. I just got back into Java development after a 5-year (management/architecture) hiatus and after spending quite some time looking for a framework that was easy to learn and attractive, I chose Stripes.

    I just finished w/ Freddy Daoud’s great book and am working on my 1st app. I’ve got something up and running within two days–remember I’ve not touched coding in 5 years!

    Your point about keeping your Actions clean is well taken. Right now, all my persistence is taking place in my actions and things are getting too busy. I’ll read the article you referenced: “simple Stripes Interceptor which injects dependencies into Actions”–thanks for that as well.


  2. Nice, comprehensive blog entry… one thing not covered here was deployment. Did you deploy on a single server instance or on a cluster? If clustered, did you encounter any ‘funnies’? I’d be very interested in your experiences on that side of the fence.


  3. Having used Stripes for a few years now and deployed around 20 projects I can strongly support the usage of Stripes for your next java based web-project. It is easy to set up and you start on day one with delivering results instead of configuring xml files like you would in many other frameworks.

    The support of the mailing-list for stripes and the ease of setting it up boost productivity by a magnitude.

    It’s simple, it can’t do everything, but leave the advanced stuff for later and start being productive today. – Choose Stripes.


  4. Hi Christian,

    Very nice article! Thank you for your detailed analysis, it is interesting to read.

    Cheers,
    Freddy


  5. Hi Christian:

    Thanks for the IntelliStripes mention

    Mario Arias


  6. Glad you like it. We use stripes at a very large online retailer with good success (several hundred million pageviews a month). The one thing that sucked for us was their use of flash scope had a reference to a non-serializable object (a http request wrapper) and forced us to go without sessions (we don’t use sticky sessions for a lot of reasons). Not an overly bad decision, but prevents some handy features, like redirects with flash scope usage.

    Other than that it works great. We use the interceptors for certain things too. The biggest benefit though is the low configuration and auto discovery of things. Combined with the UrlRewrite library and you have a great combination.


  7. Interesting article!

    Regarding Spring MVC’s singleton Controller model: if you bind request parameters to a @Controller handler method argument that is a JavaBean, which is the most common technique, there is no annotation required. @RequestParam is also optional when binding single parameter values. Most @Controller handler methods I write use no annotations other than @RequestMapping, which is concise and improves code readability. What lots of annotations do you end up writing in your Spring MVC handler methods?

    I personally find it more natural to author stateless @Controllers with independent handler methods that process requests to the same logical resource. What I like about this is everything related to processing a request is local to a handler method. With the Stateful approach, model state is shared across all handler methods–what do you do when the model differs between these methods? Don’t you end up with a lot of null instance variables, and resulting confusion over what exactly the view can access? Or do you prevent this by introducing additional Action beans? Do you ever feel doing that impacts your Controller design in a unnatural way? I’m curious your thoughts on this.


  8. @Keith:

    Thanks for the thoughtful response. I think that there are different scenarios when it comes to binding in most web applications. We have some case where we bind into rich graphs of javabean-style objects (quite rare though) and on the other end of the spectrum we have our single parameter controllers. There are some in-between cases, where a few parameters capture what is needed to handle the request, and no object yet exists to capture them (and creating one may seem like overkill). In this scenario I prefer how it’s dealt with in Stripes than in Spring MVC. I didn’t mean to imply that all Spring controllers _must_ have many annotations. From my experience however, we’ve ended up with a number of such handler methods over the course of a project. Reviewing section 13.11 of the Spring Reference Guide reveals a number of method-parameter annotations in what seem like very simple examples.

    I want to be clear that I view this mostly as a conversation about aesthetics. You might prefer to create simple javabeans to bind into where I prefer letting the action be that bean. I personally have a fairly strong dislike for method parameter annotations. Getting that out of the way, I’ll answer your other questions and try to clarify why it is that I prefer the aesthetics of the Stripes approach.

    I like keeping my Actions simple. Multiple handlers are okay, but when the parameters or model differ too much between handlers, it becomes difficult to maintain for exactly the reasons you mentioned. In this case it’s an easy refactor to split an action into two or more simpler actions. I would describe Stripes Actions as pretty small and granular. A single page with dynamic asynchronous behavior would likely be backed by multiple Actions (and likely a single @Controller if I were using Spring). I wouldn’t map a single Stripes Action to a single Spring Controller in most cases.

    While I’m not religious about it, I have been moving away from binding straight into domain objects for a variety of reasons: invariant enforcing, protecting state, immutable value objects, etc. This is a huge topic that I plan on writing more about soon. An Action happens to be a great place to bind a collection of values before doing something with them, like instantiating a value object or updating a small subset of the state on an entity. Sure, I could create a simple javabean that collects these fields, but I’m pretty happy with letting the action be that for me.

    I very much like the stateless approach for my services, repositories, and many other collaborators beneath the view layer. And it was quite interesting to me when I started feeling like the Stripes model was a better fit for how I think about the view layer.

    Another small perk: with the action as the root of the model, using the <jsp:useBean …/> declaration (see above) allows for modern IDEs to give great feedback about what is available to the view. It small, but nice and I don’t know how to get the same when the model is backed by generic map.

    Given all of this, the fact that Stripes offers CleanURLs for RESTy URLs and binding, <s:url …/> and <s:param …/>to help with DRY, and fantastic convention over configuration, I think it’s a great framework and it turned out to be a good choice for our project. Don’t get me wrong, I love the work that SpringSource has done and I’m excited to check out all of the new stuff that’s coming up in 3.0. While Spring MVC may no longer be my first choice for the web tier (it was since 2004), the rest of the Spring stack is likely to be part of my Java toolbox for as long as I’m using Java.


  9. Hi Christian,

    I’m wondering now that this blog post is several months old if you are still using Stripes or considering other frameworks again? I’ve been using both Stripes and Spring and find that Stripes is a better match for my environment mainly because of its osimplicity and use of convention over configuration. My main concern with it is that I don’t see any wide scale adoption of it.

    Thanks.


  10. Hello Christian,

    Could you say a little more about your integration of Spring Security with a Stripes project? I’m currently experimenting with using a LoginActionBean as a login page for Spring Security, and I’d like to know more about your specific experience.


  11. Great article, are you folks still using Stripes? I am using Velocity in front of Stripes (I know they are not the latest/greatest but they really do their jobs excellently) and its wonderful compared with Struts, Spring etc! Totally natural for a UI developer to handle VTL (velocity template language which is very simple), complete separation of concerns, and you can even use Velocity to generate your Stripes model 😀

Your feedback