URL Binding in Stripes

The best thing about Stripes is that it follows the convention over configuration practice. One of the most convenient conventions is the automatic generation and binding of URLs to the action bean class names. During development this is very helpful since you don’t need to keep in sync a configuration file as you add or delete action beans. To generate the URLs Stripes follows certain rules, of course as with everything else in Stripes you can change the default rules if they don’t meet your needs.

First lets see the default rules and then I’ll discus  how to change them if needed.

Stripes will automatically load all your action beans at start up, but we need to tell Stripes where to start looking for action beans, we need to declare at least one root package. We can do this by specifying the ActionResolver.Packages init-param in the declaration of the StripesFilter in web.xml which is the only mandatory configuration parameter. If you keep your action beans in different packages you can add all of them separated by comma as shown in the following spinet.

<filter>
  <filter-name>StripesFilter</filter-name>
  <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
  <init-param>
    <param-name>ActionResolver.Packages</param-name>
    <param-value>com.pk1.action,com.pk2.action</param-value>
  </init-param>
</filter>

Now that Stripes knows how to load the action beans lets see how the URLs are generated and bound to the action bean class names. Lets suppose we have the following action bean:


package com.action.test;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;

public class HelloActionBean implements ActionBean {
	private ActionBeanContext context;

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

    @DefaultHandler
    public Resolution view () {
	return new ForwardResolution("/WEB-INF/jsp/home.jsp");
    }
}

Our action bean class name is HelloActionBean and it’s located under the package com.action.test; to refere to this action in a jps we can use the following name /test/Hello.action.

As mentioned previously to generate the URLs Stripes follows certain rules.
1. It will remove the package name up to and including the the following names if present in the package [action, stripes, web, www]. That’s why we refer to the /test/Hello.action without the full package name since the package name of this bean includes the token action and is removed up to that token.
2. It will remove from the class name the following suffixes [ActionBean, Action or Bean]. That’s why we have the /test/Hello.action instead of /test/HelloActionBean.action.
3. It will convert package name and class names to paths and change all periods to forward slashes. Instead of [test.Hello.action] we have /test/Hello.action
4. It will append the .action to the end of the striped bean name.

Fast forward:
rule 1: from com.action.test.HelloActionBean we get test.HelloActionBean
rule 2: from test.HelloActionBean we get test.Hello
rule 3: from test.Hello we get /test/Hello
rule 4: from /test/Hello we get /test/Hello.action

Lets see some examples of how this works:
com.pk1.action.HelloActionBean –> /Hello.action
com.pk1.web.HelloAction –> /Hello.action
com.pk1.www.HelloBean –> /Hello.action
com.pk1.stripes.HelloActionBean –> Hello.action
com.pk2.module.HelloActionBean –> /com/pk2/module/Hello.action

Some controversial examples:
com.pk1.web.MyActionBeanX  –> /MyActionBeanX.action (the ActionBean is not removed since it is not at the end)
com.pk1.www.ActionBean –> /.action (the ActionBean is removed based on the rule number 2)
http://www.web.action.stripes.HelloBean –> /Hello.action (all package tokens are removed since they are in the list of rule number 1)

Now that we know the rules for generating the URLs, lets see how we can change them to meet our needs. This process is quite easy.
The class that implements the rules for URL binding is the NameBasedActionResolver. To change the rules for URL binding you just need to extend this class and override the getBasePackages() and/or getBindingSuffix(), (if you change the suffix do not forget to change url-pattern of the servlet mapping in the web.xml). You can change completely the behavior of URL binding by overriding the getUrlBinding(String). Your custom class for the URL bind rules should be registered as a Stripes extension.

Here is an example of how to change the suffix from [action] to [go]. As I said this is quite easy, it requires two steps:

1. Change the servlet mapping in web.xml


<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
	<url-pattern>*.go</url-pattern>
</servlet-mapping>

2. Extend the NameBasedActionResolver and override the getBindingSuffix()


package com.ext;

import net.sourceforge.stripes.controller.NameBasedActionResolver;

public class CustomActionResolver extends NameBasedActionResolver {
	@Override
	protected String getBindingSuffix() {
		return ".go";
	}
}

Note that this is an extension and extensions are loaded automatically by Stripes but as with action beans we need to tell Stripes where to look for. To configure extensions we need to add another init-param to the StripesFilter as we did for the action beans. The parameter name for the extensions is [Extension.Packages].
Here is an example:


<init-param>
	<param-name>Extension.Packages</param-name>
	<param-value>com.ext</param-value>
</init-param>

Extending the NameBasedActionResolver we can tweak the URLs in any way we want and as you can see it is quite easy, an interesting tweak would be to implement clean URLs but that will be another post.

Advertisements

2 thoughts on “URL Binding in Stripes

  1. Pingback: The Stripes framework « 110j

  2. Pingback: Clean and usable URLs in Stripes « 110j

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s