Name | Convention Plugin |
---|---|
Publisher | Brian Pontarelli Apache Software Foundation |
License | Open Source (ASL2) |
Version | Bundled with Struts from 2.1 .1-SNAPSHOT on |
Homepage | You're at the homepage |
Download | Part of the Struts2 distribution |
http://cwiki.apache.org/confluence/display/WW/Convention+Plugin |
Wiki Markup |
---|
{rate:title=Rating|theme=dynamic} |
...
- Action location by package naming conventions
- Result (JSP, FreeMarker, etc) location by naming conventions
- Class name to URL naming convention
- Package name to namespace convention
- SEO compliant URLs (i.e. my-action rather than MyAction)
- Action name overrides using annotations
- Interceptor overrides using annotations
- Namespace overrides using annotations
- XWork package overrides using annotations
- Default action and result handling (i.e. /products will try com.example.actions.Products as well as com.example.actions.products.Index)
The Convention Plugin should require no configuration to use. Many of the conventions can be controlled using configuration properties and many of the classes can be extended or overridden.
Setup
In order to use the Convention plugin, you first need to add the JAR file to the WEB-INF/lib directory of your application.
Hello world
Now that the Convention plugin has been added to your application, let's start with a very simple example. This example will use an actionless result that is identified by the URL. By default, the Convention plugin assumes that all of the results are stored in WEB-INF/content. This can be changed by setting the property struts.convention.result.path in the Struts properties file to the new location. Don't worry about trailing slashes, the Convention plugin handles this for you. Here is our hello world JSP:
Code Block | ||||
---|---|---|---|---|
| ||||
<html>
<body>
Hello world!
</body>
</html>
|
If you start Tomcat (or whichever J2EE container you are using) and type in http://localhost:8080/hello-world into your browser you should get this result:
Code Block | ||||
---|---|---|---|---|
| ||||
Hello world!
|
This illustrates that the Convention plugin will find results even when no action exists and it is all based on the URL passed to Struts.
Code behind hello world
Let's expand on this example and add a code behind class. In order to do this we need to ensure that the Convention plugin is able to find our action classes. By default, the Convention plugin will find all action classes that implement com.opensymphony.xwork2.Action or whose name ends with the word Action in specific packages.
These packages are located by the Convention plugin using a search methodology. First the Convention plugin finds packages named struts, struts2, action or actions. Any packages that match those names are considered the root packages for the Convention plugin. Next, the plugin looks at all of the classes in those packages as well as sub-packages and determines if the classes implement com.opensymphony.xwork2.Action or if their name ends with Action (i.e. FooAction). Here's an example of a few classes that the Convention plugin will find:
Code Block | ||||
---|---|---|---|---|
| ||||
com.example.actions.MainAction
com.example.actions.products.Display (implements com.opensymphony.xwork2.Action)
com.example.struts.company.details.ShowCompanyDetailsAction
|
Each of the action classes that the plugin finds will be configured to respond to specific URLs. The URL is based on the package name that the class is defined in and the class name itself. First the plugin determines the namespace of the URL using the package names between the root package and the package the class is defined in. For our examples above, the namespaces would be:
Code Block | ||||
---|---|---|---|---|
| ||||
com.example.actions.MainAction -> /
com.example.actions.products.Display -> /products
com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details
|
Next, the plugin determines the resource of the URL using the class name. It first removes the word Action from the end of the class name and then converts camel case names to dashes. In our example the full URLs would be:
Code Block | ||||
---|---|---|---|---|
| ||||
com.example.actions.MainAction -> /main
com.example.actions.products.Display -> /products/display
com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details/show-company-details
|
You can tell the Convention plugin to ignore certain packages using the property struts.convention.exclude.packages. You can also tell the plugin to use different strings to locate root packages using the property struts.convention.package.locators. Finally, you can tell the plugin to search specific root packages using the property struts.convention.action.packages.
Here is our code behind action class:
Code Block | ||||
---|---|---|---|---|
| ||||
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorld extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
public String execute() {
message = "Hello World!"
return SUCCESS;
}
}
|
If you compile this class and place it into your application in the WEB-INF/classes or WEB-INF/lib (inside a JAR file), the Convention plugin will find the class and map the URL /hello-world to it. Next, we need to update our JSP to print out the message we setup in the action class. Here is the new JSP:
Code Block | ||||
---|---|---|---|---|
| ||||
<html>
<body>
The message is ${message}
</body>
</html>
|
If start up the application server and open up http://localhost:8080/hello-world in our browser, we should get this result:
Code Block | ||||
---|---|---|---|---|
| ||||
The message is Hello World!
|
Sub-packages and namespaces
Results and locations
Components
Extensionless URLs
Configuration reference
...