Adding and Using the Conventions Plugin

Version 6.1 by Ken McWilliams on 2012/03/03 23:27

I think every struts2 user should be using the conventions plugin.  It reduces xml to almost nothing, speeds up development time and improves readablility. I really can't think of a down side. There is a very simple example, for detailed information on the struts2-conventions-plugin see the struts2 site.

Starting with an empty Struts2 project.

All we need to do is add the struts2-conventions-plugin (using the same version as struts2) to your class path.

Using the conventions plugin is very easy!

It forms a relationship between your packages and the JSPs under WEB-INF (you can use other view technology but in this example we'll use JSPs).

Basic Rules you must obey when using conventions

  • Packages are scanned for "action", "struts" or "struts2" when such a package is found all Classes which implement ActionSupport or end with the name "Action" become actions.
  • The package structure after "action", "struts" or "struts2" become part of the name space for the action.
  • JSPs for the root namespace are found under /WEB-INF/content other name spaces are added as folders under content.
  • JSPs under /WEB-INF/content automatically become actions even if there is no corresponding action class. 
  • Action Classes will follow Java standard naming, that is camel case and the JSPs will be all lower case with hyphens between words.

Examples

The following examples use the the following:

Server: http://localhost:8080/

Context Root: Example/

So all our pages will be prefixed with http://localhost:8080/Example/

Example 1 - Create an action to display a Form (No action class required)

The following create an action to display a JSP which allows the user to enter their name, in the next example we allow them to submit it and process the results.

Create a JSP at /WEB-INF/content/enter-name.jsp

<%@taglib prefix="s" uri="/struts-tags"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Enter Name Example</title>
    </head>
    <body>
        <h1>Enter Name Example</h1>
        <s:form action="process-form">
            Please enter your name: <s:textfield name="name"/>
            <s:submit/>
        </s:form>
    </body>
</html>

To access this action: http://localhost:8080/Example/enter-name

Example 2 - Process form and display results

We need to create an action to process the name from the above example.  We know that we must put this action in a package which contains the name "action", "struts" or "struts2".

Create a package called: com.example.action (really the package structure before ".action" can be what ever you want)

Create a file in this package called: ProcessForm.java

Add the following source:

package com.example.action;

import com.opensymphony.xwork2.ActionSupport;

public class ProcessForm extends ActionSupport{
    private String name; //If this was public we could ommit the getters/setters

    @Override
    public String execute(){
        //processing goes here
        //lets do something really simple like adding Hello to the name
        name = "Hello, " + name + "!";
        return SUCCESS;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Create the JSP for this action: /WEB-INF/content/process-form and add the following content

<%@taglib prefix="s" uri="/struts-tags"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Display Processing Example</title>
    </head>
    <body>
        <h1>Display Processing Example</h1>
        <s:property value="name"/>
    </body>
</html>

That's it run the project and test it with http://localhost:8080/Example/enter-name to input a value or supply a get request by using the url, such as: http://localhost:8080/Example/process-form?name=Ken