Versions Compared

Key

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

Update formatting

...

In

...

the

...

Hello

...

World

...

lesson,

...

we

...

implemented

...

a

...

use

...

case

...

that

...

displayed

...

a

...

message

...

with

...

a

...

dynamic

...

timestamp.

...

In

...

this

...

lesson,

...

we

...

create

...

a

...

workflow

...

that

...

displays

...

input

...

from

...

a

...

data-entry

...

form.

...

The

...

form

...

will

...

ask

...

for

...

your

...

name.

...

If

...

you

...

enter

...

"Bob"

...

and

...

click

...

the

...

submit

...

button,

...

the

...

page

...

will

...

display

...

"Hello,

...

Bob

...

!".

...

If

...

you

...

don't

...

enter

...

a

...

name,

...

the

...

page

...

will

...

display:

...

"Hmmm,

...

you

...

did

...

not

...

enter

...

a

...

name.

...

Please

...

try

...

again

...

!"

...

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

...

input

...

form.

...

HTML

...

Form

...

With

...

Data,

...

Using

...

Getters

...

and Setters

Create the HTML form

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

Code Block
html
html
titlehelloName.html
 Setters


h3. Create the HTML form

The framework includes a library of special tags that you can use to write more powerful forms, but "plain old HTML forms" work just fine too.
{code:html|title=helloName.html}
<html>
<head>
	<title>A simple form with data</title>
</head>
<body>
	<p>What is your name?</p>

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

</body>
</html>
{code}

h3. Create the Action class

The HTML form submits an attribute called 

Create the Action class

The HTML form submits an attribute called "name",

...

and

...

the

...

Action

...

class

...

provides

...

a

...

corresponding

...

JavaBean

...

property.

Code Block
java
java
titleHelloWorld.java

{code:java|title=
package tutorial;

import com.opensymphony.xwork.ActionSupport;

public class HelloHelloWorld extends ActionSupport {

  String name;

  public void setName(String value)
{ {
    name = value;
   }

  public String getName()
{ {
    return name;
   }

  public String execute() throws Exception
{ {
    if (name == null || name.length() == 0)
       return ERROR;
     else
       return SUCCESS;
   }

}
{null}

h3. 

Create

...

the

...

action

...

mapping

...

We

...

can

...

just

...

add

...

a

...

new

...

action

...

mapping

...

to

...

the

...

file

...

we

...

started

...

in

...

the

...

Hello

...

World

...

lesson.

{code:xml|title=
Code Block
xml
xml
title
action.xml
}
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd">

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

  <package name="default" extends="action-default">

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

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

  </package>
</xwork>
{code}

h3. Create the success and error pages

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

Create the success and error pages

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

{code:html|title=
Code Block
html
html
title
helloName-success.jsp
}
<%@ taglib uri="action2" prefix="saf" %>
<html>
<head>
    <title>Success Page</title>
</head>
<body>
    <p>
      Hello, <saf:property value="name" />!
    </p>
</body>
</html>
{code}
{code:html|title=
Code Block
html
html
titlehelloName-error.html
}
<html>
<head>
	<title>Error Page</title>
</head>
<body>
<p>
Hmmm, you did not enter a name. Please try again!
</p>
</body>
</html>
{code}

h3. Try it\!

If you are coding along, go ahead and try your form now. Open the input page ([

Try it!

If you are coding along, go ahead and try your form now. Open the input page (http://localhost/tutorial/helloName.html

...

),

...

and

...

click

...

the

...

submit

...

button

...

to

...

see

...

what

...

happens.

...

Try

...

it

...

with

...

and

...

without

...

entering

...

a

...

name.

{:=
Warning
title
Don't
forget!
}

Compile

your

Action

to

{{

WEB-INF/classes

}}

and

restart

your

container

if

necessary.

How the code works

There are two differences between this example and the 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 helloName-error.jsp as the result. If the string "success" returns, then helloName-success.jsp is selected.

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

HTML Form With Data, Without Using Getters and Setters

In our first form, we needed to capture the field name and 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 helloName2.action:

Code Block
html
html
titlehelloName.html

{warning}

h3. How the code works

There are two differences between this example and the [Hello World] lesson.
# When the Action is called, {{setName}} is passed the contents of the {{name}} form field.
# When the Action's {{execute}} method returns, the framework has two options. If the string "error" returns, the framework will select {{helloName-error.jsp}} as the result. If the string "success"  returns, then {{helloName-success.jsp}} is selected.

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

h2. HTML Form With Data, Without Using Getters and Setters

In our first form, we needed to capture the field {{name}} and 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.

h3. Create the HTML form

Let's use the same HTML form, but change the form Action to {{helloName2.action}}:
{code:html|title=helloName.html}
<html>
<head>
  <title>A simple form with data</title>
</head>
<body>
   <p>What is your name?</p>

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

h3. Create the Action class

{code:java|title=HelloName2.java}

Create the Action class

Code Block
java
java
titleHelloName2.java
package tutorial;

import com.opensymphony.xwork.ActionSupport;
import org.apache.struts.action2.interceptor.ParameterAware;

import java.util.Map;

public class HelloName2 extends ActionSupport implements ParameterAware {

  Map parameters;

  public Map getParameters() {
    return parameters;
  }

  public void setParameters(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;
  }
}
{code}

h3. Create the action mapping

{code:xml|title=action.xml}

Create the action mapping

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

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

  <package name="default" extends="action-default">

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

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

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

  </package>
</xwork>
{code}

h3. Create the success and error pages

We can use the same error page, but we'll need a slightly different success page {{

Create the success and error pages

We can use the same error page, but we'll need a slightly different success page helloName2-success.jsp

...

.

...

The

...

only

...

difference

...

is

...

the

...

<saf:property>

...

tag.

Code Block
html
html

{code:html}
<%@ taglib uri="action2" prefix="saf" %>
<html>
<head>
  <title>Success Page - Without Using Getters and Setters</title>
</head>
<body>
  <p>
    Hello, <saf:property value="parameters.yourName" />!
  </p>
</body>
</html>
{code}

h3. Try it\!

Go ahead and try it now. Load {{helloName.html}}, enter "Bob" in the text field, and click the form submit button. You should see {{

Try it!

Go ahead and try it now. Load helloName.html, enter "Bob" in the text field, and click the form submit button. You should see helloName2-success.jsp

...

saying

...

"Hello,

...

Bob

...

!"

{:=
Warning
title
Don't
forget!
}

Compile

your

Action

to

{{

WEB-INF/classes

}}

and

restart

your

container

if

necessary.

{warning} h2. How the code works 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 {{helloName2-success.jsp}} page, {{<saf:property value="name" />}} isn't going to work any more, because there is no {{getName()}} method in the Action. Instead, {{<saf:property

How the code works

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 helloName2-success.jsp page, <saf:property value="name" /> isn't going to work any more, because there is no getName() method in the Action. Instead, <saf:property value="parameters.name"

...

/>

...

calls

...

the

...

getParameters

...

method,

...

and

...

is

...

able

...

to

...

get

...

the

...

value

...

of

...

the

...

"name"

...

field.

...

Pretty

...

neat

...

!

...

Summary

Before processing an Action, the framework matches any Action properties with request attributes. If a match is found, the attribute value is set to the Action property. The Action can process the value, and the SAF tags can present the value too. Rather than define a separate property for each attribute, you can define a single Map property instead. In that case, all the request attributes will be set to the Map automatically.

Next

Onward to Understanding Results

Prev

Return to Hello World