Arsenalist

The Toronto Raptors Blog with an Arsenal touch

Archive for April 4th, 2007

Struts 2 and Zero Configuration for Actions and Results

Posted by Arsenalist on April 4, 2007

Struts 2 (WebWork on drugs?) comes equipped with some pretty nice features, one of them being Zero Configuration where you don’t have to write any XML configuration or muck around with property files to get your application up and running. You simply specify a path to your action packages and Struts will read the classes, create actions based on the class name and register it with XWork. Once you combine this with the annotation support for action classes which enables you to define results and namespaces, the struts.xml (or should I say xwork.xml) goes out the window.

To start with, you must specify the path your action packages reside in, this can be a comma separated list:

<filter>
  <filter-name>action2</filter-name>
  <filter-class>
  org.apache.struts2.dispatcher.FilterDispatcher
  </filter-class>
  <init-param>
  <param-name>actionPackages</param-name>
  <param-value>
  com.arsenalist.action,com.arsenalist.otheractions
  </param-value>
  </init-param>
</filter>

Here’s an example of how the classes in com.arsenalist.action that extend ActionSupport (or implement Action) get mapped to a URL:

  • LoginAction: Gets mapped to login. Since this class ends with the word Action, Sturts strips Action out of the name and converts it to lowercase. If you don’t want the action to be converted to lowercase, you must set the forceLowerCase to false for the ClasspathConfigurationProvider.
  • SubmitOrder: This gets innocently mapped to submitorder.
  • SubmitActionClass: Since the action is in the middle of the class name and not at the end, this gets mapped to submitactionclass.

So the URL to call the execute() method of the LoginAction class becomes:

http://<hostname>:<port>/login.action

Remember you can call different methods in the action class provided you set the struts.enable.DynamicMethodInvocation property to true in struts.properties. The usual syntax for invoking dynamic methods applies here too, so to call the attemptLogin() method in the LoginAction class the URL will be:

http://<hostname>:<port>/login!attemptLogin.action

Now lets talk about specifying results in the action class via annotations instead of XML.

@Result(name=Action.SUCCESS,
  value="/WEB-INF/pages/login.ftl",
  type=FreemarkerResult.class)
public class LoginAction extends ActionSupport {

  public String execute() {
    return SUCCESS;
  }
  public String attemptLogin() {
    return SUCCESS;
  }
}

You can specify multiple Results using the @Results annotation. You may also specify namespaces for your actions classes using the @Namespace annotation, for example if we had declared @Namespace(”/security”) at the class level in addition to the @Result annotation, the URL to execute LoginAction.execute() would be:

http://<hostname>:<port>/security/login.action

Now if this is too much work for you and you would rather use default results instead of specifying them through annotations, fear not, there is something for you. It’s called the struts2-codebehind-plugin and instead of you specifying paths to results, it will implicitly assume the path to your result in the format of:

pathPrefix/actionName-resultCode.ext

where pathPrefix is specified in struts.xml. So an example path to a result would be /WEB-INF/pages/login-success.ftl. To use this, simply add this JAR to your classpath. Or alternately add the following to your Maven pom.xml:

<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-codebehind-plugin</artifactId>
  <version>2.0.6</version>
</dependency>

You’ll also need to specify the pathPrefix in struts.xml or alternately declare a property in struts.properties.

<constant name="struts.codebehind.pathPrefix"
          value="/WEB-INF/pages/"/>

I don’t really like this method as its too too restrictive in its nature and sometimes the same result can be returned for different actions which would introduce a redundancy in the convention.

Important Note

The one thing struts.xml buys you is having multiple actions map to the same action class. For example, if you wanted to have /doThis.action and /doThat.action map to different methods in the same class, you wouldn’t be able to do it using annotations since they force you to have one action URL per class. In most of the development I’ve done, having one class per action URL added way too many action classes to the application. If I want to process CRUD operations for a user, it would make sense to have only one UserAction class with different action paths (/user/update, /user/delete etc.) which correspond to different methods in UserAction. Of course, you can always use the /actionName!methodName.action syntax to get around this restriction of annotations but once you start integrating something like Sitemesh into your app and want your paths nicely mapped to views, you might end up wishing you had used struts.xml.

This post has moved here.

Posted in java, struts, tech | Comments Off

Game on the line? Have TJ Ford drive right and throw up a prayer

Posted by Arsenalist on April 4, 2007

Please, not TJ Ford, please God not TJ Ford again. Not the same old drive to the right and throwing up a half-ass excuse of a shot. It’s already failed us shitloads of times, not again. But lo and behold, Smitch decides to go with the play which every fan watching, no, praying hoped he didn’t go with. Sure enough poor Ford expectedly missed it and gave the old “Aww man, almost had it” look which we’ve seen too many times in the past. The Raptors deserved better in this game, they fought back from a late deficit only to be sacrificed at the altar by Mitchell who wanted to prove that the only “game-winning” play in his book does actually in fact work. It bit us in the ass again.

Considering we have Parker, Dixon, Mo Pete who are all better shooters than Ford, why Sam Mitchell opted to go with a one-on-one move is puzzling, especially seeing how we were having good success against Miami anytime we did move the ball on offense - we didn’t make a lot of shots we usually make but they were still there for the taking. If that wasn’t bad enough, with the Raptors down three now, he again ran a play for TJ Ford, not exactly a prolific three point shooter, of course he missed it and you can hardly blame him. Hitting threes isn’t in his repertoire and why me as a fan can realize that and Mitchell can’t is beyond anyones comprehension.

Let’s ignore Ford’s three point attempt for a second (although it was a sorry play given the three point shooting on this team) and talk about Mitchell going with TJ Ford alone when down one and the game on the line - remember this is just a one-on-one move with no picks or anything of the sort being set for him. Maybe he felt that Bosh (24 points) couldn’t break down Miami’s forwards even though Shaq was out of the game and wasn’t there to play help defense. What gets me is that the ball didn’t even go through Bosh, our primary double-team threat, just so we could see the options on the floor if Miami did double-team. If they would have chosen not to double-team, CB4 could’ve kicked it out for Ford’s desperate attempt or even made the move himself.

Botched crunch time plays are what kills team down the stretch in the playoffs and despite the Raptors’ success this season, I have little faith in Mitchell’s X’s and O’s when the game is on the line. This same play has burned us four times this season and it was almost shocking to see Ford drive to his right and hoist up the exact same shot he did against Seattle, Cleveland etc. with the exact same result. Ford had an overall bad game but bad games happen, he made some poor decisions but the decision that ultimately cost us the game was Sam Mitchell’s.

This was a tough loss, what made it tougher was that we could’ve easily won despite playing poorly for the majority of the game. I have to give some props to James Posey for knocking down four clutch free throws for Miami, it killed us. Here’s q quick recipe for beating Miami in the playoffs if we do meet them.

  • Play them even on the boards.
  • Contain their outside shooting, have Mo Pete stick Kapono.
  • Move Shaq out of the paint via Rasho and run pick ‘n rolls between Bosh/Ford/Calderon.
  • Give Antoine Walker all the space he needs on the perimeter. Same for Haslem, except beyond the elbow.
  • Long outlet passes after made FTs and shots, force Miami to spend some energy.
  • Make Wade play defense by going though his man on offense at least every other possession, thats Parker or Ford.

I know it’s easier said than done. Check out Chasin’s highlights from this game.

Posted in Raptors, heat, nba | 7 Comments »