ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Java Web Development with Stripes
Pages: 1, 2, 3

Let's look at an example of what Stripes will do with our Hello World example class. Since the HelloWorldAction class is in the /WEB-INF/classes path and implements ActionBean, it will be recognized as a Stripes servlet. In our example, the fully qualified name of the class is com.myco.web.stripes.action.example.HelloWorldAction. The fully qualified name is then translated to a URL binding by performing these rules:



  1. Substring the fully qualified class name with each occurrence of strings that match www, web, stripes, or action. In our example, we have three of the four matches in the package name. This will leave us with "example.HelloWorldAction".
  2. Remove the strings "Action" and " Bean" from the end of the class name if they exist. This will result in "example.HelloWorld" since our class ended with Action.
  3. Now we substitute slashes for periods which results in "example/HelloWorld"
  4. Finally, we add the binding suffix to the end (.action by default) which completes the URL binding. The final result is "example/HelloWorld.action".

Now that Stripes found the ActionBean class and created a URL binding for it, they will be cached in a java.util.Map<String, Class<? extends ActionBean>> where the key is the URL binding and the value is the Class that implements ActionBean. Here is what our example will look like in the Map:

URL Binding ActionBean class
/example/HelloWorld.action com.myco.web.stripes.action.example.HelloWorldAction

The second component we need to discuss is how Stripes will translate the URL binding back to the ActionBean class you are trying to work with. This is responsibility of the Stripes dispatcher Servlet which is configured in the web.xml file like this:

  
 <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>

One of the responsibilities of the StripesDispatcher is to resolve a URL to a Stripes ActionBean class. When the user invokes the URL http://host/uri/example/HelloWorld.action, the Stripes dispatcher servlet will look inside the URL binding Map and find the com.myco.web.stripes.action.example.HelloWorldAction class and instantiate an instance of it. Finally, the index method will be invoked since it was defined annotated as the default handler and an event was not specified in the URL.

What if we wanted to execute the hello method in the HelloWorldAction class directly? The URL would need to include the event name as a request parameter like this:

http://host/uri/example/HelloWorld.action?hello=&firstName=Mark&age=13

Notice that we do not specify a value for the hello request parameter. In this case, the StripesDispatcher will recognize a match for the hello request parameter name and a method name in HelloWorldAction class that has the method signature public Resolution hello(). The method names are cached at initialization in a separate Map for performance.

We have now seen the basics of Stripes and how to create simple actions and some details about how the framework operates. By doing some initial configuration in web.xml, we are able to avoid having a separate XML configuration files to wire together our presentation components. This is important for several reasons. First, you can look at a URL and instantly know what class to look at if you need to make any modifications. Second, we do not need a separate tool to assist us when the configuration file becomes large and unmanageable. By eliminating this configuration file, we no longer have to feed the framework with lots of metadata. Finally, we do not need to supply ongoing maintenance of a separate file that describes how our components are related to each other.

Ajax

So what about more advanced functionality? Let's see how Stripes handles Ajax. We will modify the Hello World example above with an Ajax call that refreshes content in place. This example will demonstrate how to use Prototype to provide the Ajax call to the Stripes action. The source for this example can be referenced in the resources for this article. First, let's modify the Hello.jsp to include the Prototype JavaScript library references. We will also add a JavaScript function for the Ajax call and change the submit button to reference a new button with an onclick event :

        
<%@ taglib prefix="stripes" 
            uri="http://stripes.sourceforge.net/stripes.tld" %>
<html>
  <head>
    <title>Stripes Hello World</title>
    <script 
        src="${pageContext.request.contextPath}/js/prototype.js"
        type="text/javascript"></script> 

    <script type="text/javascript">
       function sayHelloAjax() {
          var myAjax = new Ajax.Updater('hello',
          "<stripes:url 
               beanclass="com.
                          myco.
                          web.
                          stripes.
                          action.
                          example.
                          HelloWorldAction"
               event="sayHelloAjax"/>",
          {
              method: 'get',
              parameters: Form.serialize('helloForm')
          });
        }
    </script>
  </head>
  <body>
    <stripes:errors/>
    <stripes:form 
        beanclass="com.
                   myco.
                   web.
                   stripes.
                   action.
                   example.
                   HelloWorldAction" 
        id="helloForm">
        Say hello to: <br>
        First name: <stripes:text 
                          name="person.firstName"/><br>

        Age:<stripes:text name="person.age"/><br>

        <stripes:button
                name="helloAjax"
                value="Say Hello" 
                onclick="sayHelloAjax()"/>

        <div id="hello"></div>

    </stripes:form> 
  </body>
</html>

The stripes:button has an onclick event that will call the sayHelloAjax method in the HelloWorldAction class and return the results in the div tag called hello. Here is the new method that we need to introduce in the HelloWorldAction class:

 
public Resolution sayHelloAjax(){
  return new ForwardResolution("SayHelloAjax.jsp");  
}

This method does not have to do much since the binding of the first and last name is taken care of by Stripes. Therefore, the only responsibility of this method is to forward to a partial page called SayHelloAjax.jsp. Here is the contents of SayHelloAjax.jsp:

        
<h2>Hello ${actionBean.person.firstName} your age is ${actionBean.person.age}!</h2>

Spring Integration

Stripes also has built in integration with Spring. You can inject Spring beans or services into your Action automatically. In Stripes fashion, this does not require external configuration aside from your Spring context configuration. If we have a bean defined in our Spring configuration like this:

  
<bean id="personService" parent="abstractTxDefinition">
  <property name="target">
    <bean class="com.myco.service.impl.PersonServiceImpl"/>
  </property>
</bean>

To inject the person service into a Stripes action, add a property and setter that matches the name of the Spring bean. Stripes provides the @SpringBean annotation to locate the correct Spring bean to inject into the action class. Here is an example of what needs to be included in the Stripes action:

  
private PersonService personService;

@SpringBean
public void setBlogService(BlogService blogService) {
  this.blogService = blogService;
}

This article cannot cover all of the advanced features of Stripes. However, the Stripes documentation is very comprehensive. Stripes also includes a layout manager similar to Tiles without external configuration. Additionally, interceptors can also be used across life-cycle events, file upload, and a lot more.

Conclusion

Stripes is a powerful yet simple Java web framework. Stripes takes advantage of Java 5 features such as annotations and generics, which allows Java developers to avoid maintaining external configuration files and increase productivity. Stripes makes difficult web development tasks easy and makes simple tasks even easier.

Resources

Mark Eagle is a Senior Software Engineer at MATRIX Resources, Inc. in Atlanta, GA.


Return to ONJava.com.