Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The form will ask for your name. If you enter "BobZaphod" and click the submit button, the page will display "Hello, BobZaphod!". If you don't enter a name, the page will display: "Hmmm, you did not enter a name. Please try again!"

HTML Form With Data, Using Getters and Setters

In the Hello World lesson, there were three components: the Action class, the result page, and the action mapping. In this lesson, we will add a fourth component: an a input form.

HTML Form With Data, Using Getters and Setters

...

Create a HTML input form

The framework includes a library of special tags that you can use to write more powerful dynamic forms, but "plain old HTML" forms " work just fine too.

Code Block
html
html
titlehelloNameHelloName.html
<html>
<head>
    <title>A simple HTML form with data</title>
</head>
<body>
    <p>What is your name?</p>

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

</body>
</html>

...

The HTML form submits an attribute called "name", and the Action class provides a corresponding JavaBean property.

Code Block
java
java
titleHelloWorldHelloName.java
package tutorial;

import com.opensymphony.xworkxwork2.ActionSupport;

public class HelloWorldHelloName extends ActionSupport {

  String name;

 public voidString setName(String value)
{execute() throws Exception {
     name = value; if  }
 public String getName()
{(getName() == null || getName().length() == 0)
            return nameERROR;
     }
 public String execute() throws Exception
{   else
            return SUCCESS;
    }

    private ifString (name;

   == nullpublic || name.lengthString getName() =={
 0)       return ERROR;     elsename;
    }

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

Create the action mapping

...

Code Block
xml
xml
titlestruts.xml
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <include file="struts-default.xml" />

  <package name="defaulttutorial" extends="struts-default">

      <action name="helloWorldHelloWorld" class="tutorial.HelloWorld">
          <result name="success">helloWorld>/tutorial/HelloWorld.jsp</result>
      </action>

      <action name="helloNameHelloName" class="tutorial.HelloName">
          <result name="success">helloName>HelloName-success.jsp</result>
          <result name="error">helloName>HelloName-error.jsp</result>
      </action>

  </package>

</struts>

Create the success and error pages

The Action can select between two outcomes, "success" and "failure".

Code Block
html
html
titlehelloNameHelloName-success.jsp
<%@ taglib uri="action2/tags" prefix="safs" %>
<html>
<head>
    <title>Success Page</title>
</head>
<body>
    <p>
      Hello, <s:property value="name" />!
    </p>
</body>
</html>
Code Block
html
html
titlehelloNameHelloName-error.html
<html>
<head>
    <title>Error Page</title>
</head>
<body>
<p>
Hmmm, you did not enter a name. Please try again!
</p>
</body>
</html>

...

If you are coding along, go ahead and try your form now. Open the input page (http://localhost:8080/tutorial/helloName.html), and click the submit button to see what happens. Try it with and without entering a name.

...

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

  1. When the Action is called, setName is passed the contents of the name form field.
  2. When the Action's execute method returns, the framework has two options. If the string "error" returns, the framework will select helloNameHelloName-error.jsphtml as the result. If the string "success" returns, then helloNameHelloName-success.jsp is selected.

Let's try a slightly different approach to solve the same user use case.

HTML Form With Data, Without Using Getters and Setters

In our first form, we needed to capture the field name and to . To do that, we added the getters and setters getName and setName to the Action class, as well as the private variable name. A larger application with dozens of forms and hundreds of form fields could need several hundred getters and setters. Let's try that same use case again, but without the JavaBean methods.

Create the HTML form

Let's use the same HTML form, but change the form Action to helloName2HelloName2.action:

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

   <form action="helloName2HelloName2.action" method="post">
     <p><input type="text" name="name"></p>
     <p><input type="submit" value="Submit your name." /></p>
   </form>
</body>
</html>

...

Code Block
java
java
titleHelloName2.java

package tutorial;

package tutorial;

import com.opensymphony.xworkxwork2.ActionSupport;
import org.apache.struts.action2struts2.interceptor.ParameterAware;

import java.util.Map;

public class HelloName2 extends ActionSupport implements ParameterAware {

  Map parameters;

  public Map getParameters() {
    return parameters;
  }

  public voidString setParametersexecute(Map parameters) {
    this.parameters = parameters;
  }

  public String execute() {
    String[] name = (String[]) parameters.get("name");
        if (name == null || name[0] == null || name[0].length() == 0)
            return ERROR;
        else
            return SUCCESS;
    }

    Map parameters;

    public Map getParameters() {
        return parameters;
    }

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

Create the action mapping

Code Block
xml
xml
titleactionstruts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xworkstruts PUBLIC
        "-//OpenSymphonyApache Software GroupFoundation//XWork 1DTD Struts Configuration 2.0//EN"
        "http://wwwstruts.opensymphonyapache.comorg/xworkdtds/xworkstruts-12.0.dtd">

<xwork><struts>
    <include file="actionstruts-default.xml" />

    <package name="defaulttutorial" extends="actionstruts-default">

        <action name="helloWorldHelloWorld" class="tutorial.HelloWorld">
            <result name="success">helloWorld>/tutorial/HelloWorld.jsp</result>
        </action>

        <action name="helloNameHelloName" class="tutorial.HelloName">
            <result name="success">helloName>HelloName-success.jsp</result>
            <result name="error">helloName>HelloName-error.jsp<html</result>
        </action>

        <action name="helloName2HelloName2" class="tutorial.HelloName2">
            <result name="success">helloName2>HelloName2-success.jsp</result>
            <result name="error">helloName>HelloName-error.jsp<html</result>
        </action>

    </package>

</xwork>struts>

Create the success and error pages

We can use the same error page, but we'll need a slightly different success page helloName2HelloName2-success.jsp. The only difference is the <saf<s:property> tag.

Code Block
html
html
<%@ taglib uri="action2/tags" prefix="safs" %>
<html>
<head>
    <title>Success Page - Without Using Getters and Setters</title>
</head>

<body>
  <p>
    Hello, <saf<s:property value="parameters.yourNamename" />!
  </p>
</body>
</html>

Try it!

Go ahead and try it now. Load helloNametutorial/HelloName2.html, enter "BobZaphod" in the text field, and click the form submit button. You should see helloName2HelloName2-success.jsp saying "Hello, BobZaphod!"

Warning
titleDon't forget!

Compile your Action to WEB-INF/classes and restart your container if necessary.

...

Instead of a setter setName accessing a private variable name in the Action class, setParameters magically extracts everything from the request object and puts the attributes into a private local Map, parameters. In the execute method, we can get the value from the parameters Map instead of looking for a name property. So far so good.

Back on the helloName2HelloName2-success.jsp page, <saf<s:property value="name" /> isn't going to work any more, because there is no getName() method in the Action. Instead, <saf<s:property value="parameters.name" /> calls the getParameters method, and is able to get the value of the "name" field. Pretty neat!

...