Você está na página 1de 2

From: http://ciplogic.com/index.

php/blog/50-struts2-best-practices

Struts2 Best Practices


After reading Struts 2 in Action (a definite read for people who have no experience at all using struts 2), and after finishing a project and actually delivering it to the customer, and in the middle of the second one, I've decided to write down the best practices that I follow. The reason why i'm writing this is that I couldn't find real case examples of good patterns to follow in developing a struts2 application, even the best practices from that book are quite slim, and I'm not going to reiterate them here.

Tooling

Buy IntelliJ Idea. I have no words to describe how much more advanced is this compared to eclipse. Jump to definitions of actions, jump to implementing classes, you can pick what action you want to go to from a class (if multiple actions are mapped to the same class), etc. Simply outstanding.

Buy JRebel if you have I18N in your application. Although they brag to have struts2 support I couldn't make it work (even if conforming to their website should be "brainless" to do it). What it does well though is reloading of classes (like adding methods and co.) and bundle reloading.

Programming Style

Don't write any code until you fully understand the ActionContext and the ValueStack, and how the property resolving takes place. Otherwise all the iterators and push constructs in the JSP will simply look like voodoo (I am talking from experience here).

Write tests for your actions. It does seem a bit hard, but it is actually quite simple. Just add this dependency in your maven2 pom.xml file, and just create tests:

<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-junit-plugin</artifactId> <version>2.1.8.1</version> </dependency>

Don't create actions with multiple methods. "execute" and the operation you want to execute (e.g. "createUser") should be enough. Execute would be used for rendering a jsp/ftl/vtl template, and the action will be used to actually do your business requirement.

All your validations, try to express them via annotations on the business method (@Validations), and if you can't since they're to complex, and expressions won't cut it, simply implement the validate() action. Never put validations in the model (if you're using ModelDriven actions). The reason is that you always have to check two files in order to see if the business method will be called. Another thing to keep in mind is if you use annotations AND multiple methods, struts 2 for some reasons collects all the annotations from all the methods and applies them against the current method being called. (as of 2.1.8.1)

Use only one I18N package.properties file for the whole project. If the project gets big it's hard to track which key is where and you'll end up with lots of duplicate keys, and the fear of deleting the keys since you don't know who uses them will be there constantly; unless you're doing some funky searches against the package name in the java sources, and in the struts.xml config files.

Not fun at all.

Preffer interceptors over servlet filters. The only reason why you would want servlet filters is to intercept resources that are not actions. Otherwise the access to the ActionContext is invaluable. Both of them are fairly lightweight so I see no reason in having things that do the same thing in two places (web.xml and struts.xml).

Create interceptors to inject services for you (like EJBs, or whatever counterparts are in spring). Your methods in the action should become simple wrappers over the actual business services. Also it becomes trivial to test, since the tests will also simply inject mocks of the actual services. Don't be afraid to create custom interceptors for whatever you need them. They are extremely lightweight A "full" action implementation would be along these lines, so it is imediatelly clear what it does, what validations does it require, and is trivial to test:

public class RegisterUserAction extends ActionSupport { // ... private String username; // + getter/setter @EJB private UserService userService; // no getter/setter, set by interceptor public void validate() { // custom complex validations } @Validations( // ... most of the time validate() is not needed. ) public String registerUser() { try { userService.registerUser(username); } catch (Exception e) { LOG.error(e.getMessage(), e); addFieldError("some_field", getText("some_specific_error_key"); return INPUT; } return SUCCESS; } // execute is mapped as excluded in struts.xml for validations public String execute() { return SUCCESS; } // ... }
That would be it. As usual, I'm extremely interested in your feedback.

Have fun programming with struts 2.

Você também pode gostar