---
layout: getting-started
title: Coding actions
---
## Coding actions

This tutorial assumes you've completed the [Using Struts 2 Tags](using-tags.html) tutorial and have a working using-tags project. The example code for this tutorial, coding-actions, is available for checkout from the Struts 2 GitHub repository: [https://github.com/apache/struts-examples](https://github.com/apache/struts-examples).

### Introduction

Coding a Struts 2 Action involves several parts:

1. Mapping an action to a class
2. Mapping a result to a view
3. Writing the controller logic in the Action class

In the previous tutorials we covered how to configure Struts to map a URL such as `hello.action` to an Action class such as `HelloWorldAction` (specifically the execute method).

**Action Mapping**

```xml
<action name="hello" class="org.apache.struts.helloworld.action.HelloWorldAction" method="execute">
    <result name="success">/HelloWorld.jsp</result>
</action>
```

The Action mapping above also specified that if the `execute` method of class `HelloWorldAction` returns `success` then the view `HelloWorld.jsp` will be returned to the browser.

This tutorial will introduce you to the basics of writing the controller logic in the Action class.

### Struts 2 Action Classes

Action classes act as the controller in the MVC pattern. Action classes respond to a user action, execute business logic (or call upon other classes to do that), and then return a result that tells Struts what view to render.

Struts 2 Action classes usually extend the `ActionSupport` class, which is provided by the Struts 2 framework. Class `ActionSupport` provides default implementations for the most common actions (e.g. execute, input) and also implements several useful Struts 2 interfaces. When your Action class extends class `ActionSupport` your class can either override the default implementations or inherit them.

If you examine class HelloWorldAction from tutorial [Using Struts 2 Tags](using-tags.html) you'll see that it extends the class `ActionSupport` and then overrides method `execute`.

The method `execute` is where we placed what we want this controller to do in response to the `hello.action`.

**Method execute of HelloWorldAction**

```java
public String execute() throws Exception {
    messageStore = new MessageStore() ;

    helloCount++;

    return SUCCESS;
}
```
> Note that method execute declares it throws an Exception. We'll cover in a later tutorial how to configure Struts to handle any Exceptions thrown from the Action classes methods.

### Processing Form Input In The Action Class

One of the most common responsibilities of the Action class is to process user input on a form and then make the result of the processing available to the view page. To illustrate this responsibility, let's say that on our view page, `HelloWorld.jsp`, we want to display a personal hello, such as "Hello Struts User Bruce."

In the [Using Struts 2 Tags](using-tags.html) example application we added a Struts 2 form to `index.jsp`.

**Struts 2 Form Tags**

```xml
<s:form action="hello">
    <s:textfield name="userName" label="Your name" />
    <s:submit value="Submit" />
</s:form>
```

Make a note of the value of the name attribute for the Struts 2 textfield tag, which is userName. When the user clicks on the submit button for the above form, the action hello will be executed (`hello.action`). The form field values will be posted to the Struts 2 Action class (`HelloWorldAction`). The Action class may automatically receive those form field values provided it has a public set method that matches the form field name value.

So for the HelloWorldAction class to automatically receive the userName value it must have a public method setUserName (note the JavaBean convention discussed in tutorial [Hello World](hello-world-using-struts2.html)).

For the example application associated with this tutorial, add the following Java code to class `HelloWorldAction`.

**Add userName to HelloWorldAction**

```java
private String userName;

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}
```

To personalize the MessageStore message (recall that class MessageStore is storing the message to display) add the following Java code to the HelloWorldAction's execute method after the statement that instantiates the MessageStore object.

**Add userName value to message**

```java
if (userName != null) {
    messageStore.setMessage( messageStore.getMessage() + " " + userName);
}
```

Now build and run (`mvn jetty:run`) the application. Enter your name in the form and click the submit button. You should see the following page.

![coding_actions_form_submit_result.png](attachments/coding_actions_form_submit_result.png)

When the form is submitted, Struts will call any set methods of the HelloWorldAction class that match the form field names. So in this example method `setUserName` was called and passed the value the user entered in the `userName` form field.

On the `index.jsp` we also have a Struts 2 action link (see tutorial [Using Struts 2 Tags](using-tags.html)) that includes a query string parameter: `userName=Bruce+Phillips`. If you click on that link you should see the following result:

![coding_actions_link_with_param_result.png](attachments/coding_actions_link_with_param_result.png)

Since the query string parameter is `userName`, Struts passed the value of that parameter to the `setUserName` method.

On the view page, `HelloWorld.jsp`, you can also access the `userName` value by using the Struts 2 property tag (see tutorial [Using Struts 2 Tags](using-tags.html)). Try showing just the `userName` value on the view page.

### Summary

This tutorial introduced you to how to code the Action class so it can process user input on a form or values in a query string parameter. If the form had numerous fields, it would be cumbersome to have a set method that matches up with each form field. So our next tutorial will cover how to integrate a model class, form fields in the view and form processing in the Action class.

|Return to [Using Struts 2 Tags](using-tags.html)|or|onward to [Processing Forms](processing-forms.html)|
