20061007 Saturday October 07, 2006

ActionPack for Java

I know I haven‘t posted anything for a long time, but when you are working in downtown DC and the security measures are so draconian you don‘t have any access to the internet it makes it more difficult to keep the blog updated. So, I‘m on another J2EE project and because of the same draconian security measures I have to reinvent the wheel for most things. I can‘t even install a proper JDK! I‘m just glad Eclipse has a compiler built in. Since I have to reinvent the wheel, I might as well do it the way I wanted.

I really like the way program logic is done in Ruby on Rails, and there is no technical reason why I can‘t do that for Java. In fact, the Java Servlet specification makes it fairly easy. There are two methods of dealing with requests. You can use a Filter and FilterChain or you can use a RequestDispatcher. They take care of different aspects. The Filter allows you to inject your business logic and manipulate the HttpServletRequest and HttpServletResponse objects rather well. The RequestDispatcher allows you to use the results of another servlet/JSP/file in your response without changing the URL.

I took the tack of building my Controller so that it operated in the Filter space. I invoked the controller using reflection, which worked like a charm. I even built in logic to return a 404 response if a requested action wasn‘t implemented. I also really liked how Rails controllers fell through to rhtml files if they didn‘t send a response right then. I used the RequestDispatcher to handle that logic. In my work downtown, I figured it was much easier to fall through to a JSP than anything more elaborate. Truth be told, my Controller infrastructure is rather agnostic about what really implements the response. It could be JSPs, a Cocoon instance, etc.

In fact it would make a wonderful addition to Cocoon to tame the wild beast. In essence, the Controller framework would live as a filter that works before Cocoon gets the request and Cocoon merely responds with a pipeline. No need for CForms or other heavy work.

The true power of the Rails integration has to do with integrating the ActiveRecord and ActionPack modules. I wish I had the time to really flesh that out downtown, but I simply got myself to a point where I can move forward and get the job done. I believe I‘ll start fleshing that out — still living at a Filter layer for most things. That gives us the best of all worlds. We can use whatever we want to handle the display aspects and be as simple as merely forwarding a file or as complex as a full XML pipeline.

All this coming to a repository near you….

(2006-10-07 10:20:40.0) Permalink Trackback Comments [3]


Comments:

Amusingly, I've got something similar here that I've been playing with. It's probably nowhere near as good, since I'm really fumbling my way around Java land, and it's less generic (only uses velocity for the view portion), but other than that, same thing, rails style controller and views in a Java web app.

In case you're curious, here's what my routing setup looks like:

addRoute("/home").controller(HomeController.class).action("display");
addRoute("/recent").controller(RecentController.class).action("display");
addRoute("/user/create").controller(UserController.class).action("create");
addRoute("/user/confirm/:uuid").controller(UserController.class).action("confirm");

Those all use explicit actions, but you can also use a URL fragment of ?action to dynamically pick one.

My basic goal was to be able to set up a simple Java based web app that let me avoid hideous URLs and didn't require me to write any damn XML. Stealing good ideas from Rails was just the best way I could come up with to do that.

Posted by Garrett on October 07, 2006 at 05:04 PM EDT
Website: http://asdf.blogs.com/ #

I haven't added dynamic routing at this stage, so I am using the default "${context}/${controller}/${action}" setup. The context part is taken care of by the Servlet engine, so all I need to worry about is the Controller and the action. I don't have to do any explicit "addRoute" approaches. I use reflection to find the controller and invoke the action.

${controller} gets transformed by capitalizing the first letter, appending Controller and looking in the preconfigured package for the class. For example "user" becomes "org.dhaven.myapp.controllers.UserController".

${action} is the name of the method on the UserController class--no transformations. So "login" becomes "login()".

By making sure that the controller uses a no-argument constructor and none of the methods use arguments, its a very simple framework. Java class structure takes care of the hard work.

Posted by Berin Loritsch (72.66.48.79) on October 07, 2006 at 08:42 PM EDT #

The explicit routes come in handy if you want to send nonstandard urls to a controller or if you want more control over what parameters get passed in.

Posted by Garrett on October 07, 2006 at 10:13 PM EDT
Website: http://asdf.blogs.com/ #

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: On

Please answer this simple math question

7 + 10 =