Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

In the Using Tags lesson, we implemented a Logon form. In the Coding Actions lesson, we interpret the Logon form, and return a different result code depending on the circumstances.

If you have coded along, you can open the Logon action

Code Block
http://localhost:8080/tutorial/Logon.action

and enter a likely username and password. Since we haven't given the Action any behavior, the mapping redisplays the default Logon.jsp page.

Let's add an Action class that will make the Logon form more interesting.

The Code

Just as an example, we can examine the username and password values. If either or both properties are empty, return INPUT, so that we can collect a valid Logon. Otherwise, return SUCCESS.

Code Block
formatxml
titleLogon.java
borderStylesolid

package tutorial;
import com.opensymphony.xwork2.ActionSupport;
public class Logon

Actions

we will create a form in which you can enter your name. For example, if you enter "Bob" and click the submit button,
you'll get a page saying "Hello, Bob!". If you don't enter a name, you'll get a screen saying: "Hmm, you don't seem to have entered a name. Go back and try again please."

As before, we set everything up in four steps: create the form, create the action, register the action, and create the landing page (or in this case, pages).

1. Create the form

Paste this html into webapp/page03.jsp:

...


<html>
<head>
	<title>A simple form with data</title>
</head>
<body>
	<p>What is your name?</p>

	<form action="form03.action" method="post">
		<p><input type="text" name="yourName"></p>
		<p><input type="submit" value="Submit your name." /></p>
	</form>

</body>
</html>

2. Create the form action

Paste this code into src/lessons/Form03Action.java:

Code Block
javajava

package lessons;

import com.opensymphony.xwork.ActionSupport;

public class Form03Action extends ActionSupport {

  String yourName;

  public void setYourName(String p_yourName) {
    yourName = p_yourName;
  }

  public String getYourName() {
    return yourName;
  }


  public String execute() throws Exception {
    if (yourName == null || yourName.length() == 0)
      return ERRORif (isInvalid(getUsername())) return INPUT;
    else
      return SUCCESS;
  }

}

3. Register the action in xwork.xml:

Edit webapp/WEB-INF/classes/xwork.xml:

...


<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>
  <!-- Include webwork defaults (from WebWork JAR). -->
  <include file="webwork-default.xml" />
  
  <!-- Configuration for the default package. -->
  <package name="default" extends="webwork-default">
    <!-- Default interceptor stack. --> 
    <default-interceptor-ref name="defaultStack" /> 
    
    <!-- 02 --> 
    <action name="form02" class="lessons.Form02Action"> 
      <result name="success" type="dispatcher">page02-success.jsp</result> 
    </action> 

    <!-- 03 -->
    <action name="form03" class="lessons.Form03Action">
      <result name="success" type="dispatcher">page03-success.jsp</result>
      <result name="error" type="dispatcher">page03-error.jsp</result>
    </action>

  </package>
</xwork>

4. Create the success and error pages

Create webapp/page03-success.jsp:

...


<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
	<title>Success page for form with data</title>
</head>
<body>

Hello, <ww:property value="yourName" />!

</body>
</html>

Create webapp/page03-error.jsp:

...


<html>
<head>
	<title>Error page for form with data</title>
</head>
<body>

Hmm, you don't seem to have entered a name. Go back and try again please.

</body>
</html>

Try it

Don't forget to compile your action to webapp/WEB-INF/classes, and to restart your web application if necessary.

Go ahead and try it now: click the form submit button and see what happens. Try it with and without entering a name.

How the code works

There are only two differences between this example and the previous lesson.

  • When the action is called, its setYourName() setter is called with the contents of the form field named yourName.
  • After the action has been called (which is when its execute() method returns), WebWork has two options. If ERROR is returned, WebWork will return page03-error.jsp; if SUCCESS, page03-success.jsp. Just as in the last lesson, the <ww:property> tag calls the action's getter (in this case, getYourName()).

An html form with data, without getters or setters

For the form field named "yourName" in the previous lesson, we also had to create the getters and setters getYourName() and setYourName() in the action, as well as the private variable yourName. With dozens of forms and hundreds of form fields, you'll be typing thousands of getters and setters. That can get old fast. In this lesson, we'll repeat the last lesson, but without any of that extra typing.

1. Create the html form

Use the same JSP form from the previous lesson, but change the form action to page04.action:

...


<html>
<head>
	<title>A simple form with data</title>
</head>
<body>
	<p>What is your name?</p>

	<form action="form04.action" method="post">
		<p><input type="text" name="yourName"></p>
		<p><input type="submit" value="Submit your name." /></p>
	</form>

</body>
</html>

2. Create the form action

Paste this code into src/lessons/Form04Action.java:

Code Block
javajava

package lessons;

import com.opensymphony.xwork.ActionSupport;
import com.opensymphony.webwork.interceptor.ParameterAware;

import java.util.Map;

public class Form04Action extends ActionSupport implements ParameterAware {

  Map parameters;

  public Map getParameters() {
    return parameters;
  }

  public void setParameters(Map parameters) {
    this.parameters = parameters;
  }

  public String execute(if (isInvalid(getPassword())) return INPUT;
        return SUCCESS;
    }

    private boolean isInvalid(String value) {
    String[] yourName = (String[]) parameters.get("yourName");
    if(yourName return (value == null || yourName[0] == null || yourName[0]value.length() == 0)
      return ERROR;
    else
      return SUCCESS;
  }
}

Register the action in xwork.xml:

Edit webapp/WEB-INF/classes/xwork.xml:

Code Block
xmlxml
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>
  <!-- Include webwork defaults (from WebWork JAR). -->
  <include file="webwork-default.xml" />
  
  <!-- Configuration for the default package. -->
  <package name="default" extends="webwork-default">
    <!-- Default interceptor stack. --> 
    <default-interceptor-ref name="defaultStack" /> 
    
    <!-- 02 --> 
    <action name="form02" class="lessons.Form02Action"> 
      <result name="success" type="dispatcher">page02-success.jsp</result> 
    </action> 

    <!-- 03 -->
    <action name="form03" class="lessons.Form03Action">
      <result name="success" type="dispatcher">page03-success.jsp</result> private String username;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    private String password;
    public String getPassword() {
      <result name="error" type="dispatcher">page03-error.jsp</result>
    </action> return password;
    }
    <!-- 04 -->
    <action name="form04" class="lessons.Form04Action">public void setPassword(String password) {
      <result name="success" type="dispatcher">page04-success.jsp</result>
      <result name="error" type="dispatcher">page03-error.jsp</result> this.password = password;
      <interceptor-ref name="servlet-config"/>
    </action>

  </package>
</xwork>

Create the success and error pages

We'll use the same error page, but create a slightly different success page page04-success.jsp. The only difference is the <ww:property> tag.

...


<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
	<title>Success page for form with data</title>
</head>
<body>

Hello, <ww:property value="parameters.yourName" />!

</body>
</html>
}

}

How The Code Works

The framework automatically populates the username and password properties for us. All that's left to do is checking to see if either property is empty.

What to Remember

The Actions do the "heavy lifting" in a web application. Actions interact with data base systems and business rule engines, so that we can turn "billboard" HTML into a rich, dynamic web experience.

After doing its work, an Action returns a result code to indicate what the framework should do next. Often, the next step is to go onto the "success" result. Other times, we might need to go to an "error" result instead. In either case, the Action does not worry about generating the response, only deciding which logical result to present next.

(lightbulb) For more about Actions, see Big Picture in the Core Developers Guide.

Next

Onward to Selecting Results

Prev

Return to Using Tags

Try it

Don't forget to compile your action to webapp/WEB-INF/classes, and to restart your web application if necessary.

Go ahead and try it now. Load page04.jsp, enter "Bob" in the text field, and click the form submit button. You should see page04-success.jsp saying "Hello, Bob!"

How the code works

You've probably figured out what is going on just from looking at the code.

Instead of a setter setYourName() setting a private variable yourName in the action, setParameters() magically extracts everything from the JSP request object and puts into a private local Map parameters. Then execute(), instead of looking for a yourName variable, is able to get the value of the "yourName" field from parameters. So far so good .

Back on the page04-success.jsp page, <ww:property value="yourName" /> isn't going to work any more, because there is no getYourName() getter in the action. Instead, <ww:property value="parameters.yourName" /> calls the getParameters() getter, and is able to get the value of the "yourName" field. Pretty neat!

...