WebWork

WebWork is a much better framework compared to any of the action frameworks around. Read on to get started with WebWork. I will cover what is required to get started with WebWork and also how to integrate with Spring for a complete end-to-end solution.

Those who have used Struts know it is an action based framework. You write action classes that do certain work. You have an XML configuration file where you register the actions, the forms (beans) that the actions expect and the response mechanisms. Also you will then be painfully aware of some of the configuration headaches on large projects. One of the advantages of Struts is that it can provide a level of certainty to your web based application development model. What does that mean! For most web projects one of the existing web frameworks will suffice. Struts is well-known, well documented and relatively simple to use. You can find good people to write applications with Struts and also you will find enough good people to maintain those applications.

The power of a framework is not about how cool it is to use during development but how easy it is for others to pick it up and be productive.

Having said all of that about Struts I do think if you are coding a new project you should probably look at Tapestry or WebWork as your framework of choice. I blogged on Tapestry in my previous blog. So let me blog on about WebWork now. Point to remember: WebWork is the new Struts 2.0(still not in final form). The two frameworks have joined hands to give us anew more easy to use web framework under the Struts 2.0 banner.

Meanwhile for those starting new projects now you can still use the released versions of WebWork. Just keep a watch on news about Struts2.0. But if you look at WebWork it is immediately obvious that its a great framework. The port over to Struts 2.0 will be a lot easier if you start with WebWork. Lets begin by writing up a sample application.

  • Display a page with single form element for user name.
  • Submitting the page above will take you to a second page with a message (including the user name and a time stamp).
  • The web component will “talk” to a Spring based back end to retrieve some part of the message. In this example the business service ‘TimeService’ will give us the exact time of the day.

TheAction Class:

Here is the action class for our little application from bullet two onwards.

  • Action class Timer extends of ActionSupport (a helper action implementation).
  • The incoming form will contain a form element named ‘userName’.We provide a setter and getter for the user name attribute. WebWork will copy the form contents into this field. Rather than provide a simple field we could also provide a bean to hold the form data. Say we have a bean named UserContext with a setter and getter for user name inside of it. We then provide setUserContext and getUserContext method on our action above. In the HTML form we just have to make sure to name the text field as ‘userContext.userName’ rather than ‘userName’.
  • Anything that needs injection will need a setter method. We want to inject our Spring based back end TimeService class into this action.
  • getTime(..) is the action method that the web request will invoke to get the time of the day.
  • Think of this workflow:
    • User submits form.
    • WebWork resolves (we will see how in a moment) the request to this action and to method ‘getTime’.
    • getTime(..) will do the grunt work of calling the backend and doing all whats required to get the job done.
    • getTime(..) places the result into an action property ‘message’. There is a ‘getMessage’ which can be called to get the contents.
    • The JSP is then rendered. The JSP calls on the just executed action class to get the message for display.
    • How does the action know which JSP to render. The action method returns a SUCCESS indicator. The success indicator is mapped in the xworks.xml file to a specific JSP. Simple. We will cover the xworks.xml file a little later.

The JSP’s

Here is the JSP with a form that you submit to get the time.

  • As you can see I have used normal HTML elements in the JSP above. You could use the form tags that come along with WebWork on a real project.
  • The form action submits to ‘showTime.action’. Refer to the xworks.xml file below.
  • The text field has a name userName. This matches up with the ‘setUserName’ on the action class so that the value from the submitted form can be injected into the action.

The JSP file that serves up the response HTML is:

  • As you can see almost immediately is the custom tags that WebWork provides. There is a tag for almost everything you would want,including stuff like iteration.
  • The ww:property in this jsp refers to ‘userName’ and ‘message’.They end up getting resolved to getUserName and getMessage on our action class. The action class remember has finished executing by now and returned a SUCCESS which in the xworks.xml file resolves to the jsp above. Read on for the xworks.ml file.

Interceptors:

Here is another must-know feature of WebWork. Interceptors. These are classes that can be used to intercept the request before and after processing so that you may do useful work (like apply security, do some global logging, or say attach a hibernate session to the thread, etc.). You can create any number of interceptors and stack them in order for execution. You will always end up using the predefined interceptors provided by WebWork. More when I cover xworks.xml. Ya I know this file seems to have some magic right! Be patient.

  • The ‘ExecutionTimeInterceptor’ can do just that. Detailsare notessential here. I just want to introduce you to the concept ofinterceptors in WebWork. There is some configuration involved…holdyour breath. It will all come together.

Xwork.xml:

Now for the glue that glues all of this together…the xwork.xml file.

  • Note how we define our custom interceptor(appUserInterceptor)and apply that to the app defined interceptor stack (appInterceptorStack). The ‘defaultStack’ is a WebWork predefined set of interceptors that do some processing for us (check their web site). We basically want to add our interceptor before the ‘defaultStack’. One of the interceptors in the default stack is responsible for injecting form submission parameters into your action.This should give you a good idea of the use of interceptors.
  • With the ‘default-interceptor-ref’ XML element we apply this custom interceptor stack.
  • Finally we define our action class. Not much here but you will appreciate the simplicity and of course no more form bean stuff here(like Struts). Even this can be thrown out if we choose to use ‘XDoclet’.
  • When WebWork needs to find an action mapping this is where it comes.
  • Place this file in your web-inf/classes folder.

Spring Integration:

We need the file named webworks.properties in the web-inf/classesfolder to configure Spring.

  • webwork.objectFactory: ‘spring’to allow injecting spring beans into your actions.
  • webwork.objectFactory.spring.autoWire:Spring auto wiring. I choose ‘type’. Default is ‘name’.

I do not go into details of the Spring backend as this blog is not about Spring. The packaged example has a sample TimeService with the following interface and a configuration file named as service-registry.xml.

Web.xml

Finally here is the web.xml file.

Once deployed you should be able to get to the action directly by

http://localhost:7001/webworks/showTime.action?userName=Matt

I have not show any of the Spring related configuration. I will assume that the reader knows how to do that. The complete application can be downloaded with its ant build script by clicking here -> webworks. If you download the sample source code it will contain the Spring service implementation too. Ignore any Tiles related stuff in the downloaded zip. I have not completed WebWork and Tiles integration yet. Though it looks relatively simple.

Summary:

You should by now have a good idea (and a working sample) of building an end-to-end web application with WebWork and Spring. We are not configuration free yet. We have to maintain the xworks.xml file. My recommendation is to use XDoclet to generate the action details. That will greatly simplify things.

In comparison to Tapestry I did find WebWork a lot more easier to get started. Learning curve is a lot smaller. Myself included, I have seen a lot of people praising Tapestry but always being cautious regarding it’s learning curve. The thing I like most about Tapestry is the fact that there are no custom tag libs. Instead they throw all that is required as part of the standard HTML tag vocabulary. That makes the page easily editable in any HTML editor and also easier to work with between the web developer and the Java developer. Point to note is that both frameworks use OGNL as the expression language.