Thursday, January 31, 2008

Stripes 1.5 Feature: General Improvements

My last two Stripes articles covered Clean URLs and @StrictBinding. Today I am going a bit more general and discussing several of the smaller improvements.

Disclaimer - We know that other web frameworks have had some of these features in some form or fashion so please don't comment with "ZZZ Framework has been doing that for years.". We know. We get it.

@DontValidate

This annotation has been in Stripes for a while. We would typically use this for cancel events or just any event where you don't want validation to occur. The problem however was that type converting still happens and if it fails errors are generated and your event won't complete. This has been changed in 1.5 so now @DontValidate will also ignore type conversion.

@DontBind


Yesterday I talked about @StrictBinding and how you can control data binding using the annotation and validation. Since @StrictBinding is a class level annotation it makes it nearly impossible to do this on a per event basis. @DontValidate helps but binding still occurs. @DontBind implies @DontValidate and does not attempt any binding of data.

@HttpCache

Back in November of last year I blogged about how easy it is to create an interceptor for Stripes and we created the @NoCache interceptor. This interceptor has been added to Stripes core in 1.5 but with a twist. It is now called @HttpCache and you can control the no-cache and expires parameters via annotation attributes. Lets look at an example.

@HttpCache(expires=600)
public Resolution ajaxUpdate() {

}

The above example will allow caching but expires the document in 10 minutes.

@HttpCache(allow=false)
public Resolution ajaxUpdate() {

}

The above example disables caching and immediately expires the document. This comes in really handy when returning Resolutions to AJAX requests (especially in IE). @HttpCache can be applied at the class or method level. Method level annotations will always override class level annotations.

@Before/@After

These annotations have been available in Stripes for a while but now can be set to run on certain events. Lets look at an example.

@After(on = {"save","edit"}, stages = LifecycleStage.BindingAndValidation)
public Resolution runAfterBinding() {

}

The above method will only execute on the save and edit events. Multiple LifecycleStages can also be specified. @Before works the same way.

There are also quite a few more subtle but significant changes. Here they are in no particular order of importance.

  • When you create a link that doesn't pass validation and there is no _sourcePage to go to, you get a nice validation error report that tells you what you did wrong instead of getting a StripesRuntimeException and having to jump through hoops to figure it out

  • Incoming requests are no longer wrapped multiple times when you map StripesFilter on FORWARD. Solves problems that existed with wrapping multipart requests more than once (big explosion) and other silly issues that would occasionally arise from wrapping multiple times.

  • Enhanced checking of stuff (multiple @Validate, multiple @DefaultHandler) etc. Stripes now does a much better job at notifying you about trivial issues that can be a pain to track down. For example if you annotated two methods with @DefaultHandler Stripes would just pick one and determining why you weren't getting the expected results was time consuming. Now Stripes will throw an exception and tell you exactly what the problem is.

  • Reduced Session use. Stripes used to store encryption keys in the HttpSession. Now that it doesn't stripes doesn't force session creation of any kind.

  • Lots of changes with classpath scanning so that Stripes plays nicer with container/custom class loaders.

  • Most things in Stripes can be easily overridden to support a wide array of scenarios we can come up with as web developers. ActionResolver, ActionBeanContext, TypeConverters, just to name a few. While Stripes prides itself on zero ActionBean configuration you still need to specify init params for the Stripes Filter in the web.xml and that includes any core classes you want replaced with your own custom versions. Stripes now offers an init param, Extension.Packages, that accepts a comma separated list of packages where Stripes will auto discover and load any custom classes that would override Stripes default classes. This can significantly reduce the amount of configuration required in the web.xml


There are a few more enhancements that need to be discusses however they require their own articles respectively. I hope everyone is enjoying these articles. More to come in the days ahead, I assure you.

7 comments:

Anonymous said...

Hi Gregg,

thanks for all that articles, very nice.
But in every article i read about "events", can you explaine that a little bit please? I did not read about "events" in 1.4.x. Is that a new thing?

Thanks
Joerg

Gregg Bolinger said...

No, events have been in stripes since inception. Maybe you've heard them references as Resolutions? For example, when you post a form the name of the submit button would match the name of a method in the ActionBean that returns a Resolution. This method is the event method.

<input type="submit" name="login" />

public Resolution login() { }

jNayden said...

Respect :)
nice articles nice work :) I don't have patience to see 1.5 stable release :) I hope to be soon :)

Gregg Bolinger said...

Feel free to check the trunk from svn. It is very stable.

Anonymous said...

Thanks for all that articles!
Very good!

Would you tell me something about performance of Stripes?

We develop applications for 4-5000 intranet users, and we use Struts 1.2.x now.

Anonymous said...

Thanks for the articles, Gregg.
I am about to use Stripes again after about a year, and this is a great summary of the changes made since then.

Anonymous said...

It was very interesting for me to read this post. Thanks for it. I like such themes and anything connected to them. I definitely want to read more on that blog soon.
Alex
Cell phone blocker