The Struts web application framework makes it easy to build Java web apps using a Model-View-Controller architecture. Last time we introduced Struts tags, which let you control page output, interact with data, present information to users, and get information back from them. In that article we focused on generic tags; this time we look at user interface tags, which make it a snap to create forms and user experiences that integrate seamlessly with Java code.
UI tags let developers show data on a page and hook user input into the back end. Some of the Struts UI tags create HTML tags and allow you to hook them into your code with ease. Other tags give you additional useful options, such as the ability to show error messages, as we’ll see in a moment. Struts UI tags have particularly good support for JSP, Velocity, and FreeMarker, but should be compatible with almost any common language. The examples below use JSP.
Keep in mind three important but related concepts about Struts UI tags:
A tag is a small piece of code run within JSP, FreeMarker, or Velocity display code.
A template is a piece of code rendered by certain HTML tags. A template controls the HTML that the tags output. All the default templates are in FreeMarker, and are fine for most uses. You can extract the default templates from struts-core.jar and edit them if you need to.
A theme is a collection of templates packaged together. Themes can be extended, as we’ll see.
There are three main types of UI tag: form tags, non-form tags, and AJAX tags. If you want to use any of them on your view page, you’ll need to include a tag library directive. We’ve already seen this in the display pages in the generic tag section:
This both points at the file that describes the Struts tags, and specifies that all the Struts tags be prefixed with an “s.” If you’re interested in reading the tag TLD file, it’s in the META-INF folder of the Struts 2 core JAR.
Form tags
Here’s form.jsp, a basic input form that uses the Struts UI form tags:
Eggs And Ham FormEggs And Ham Form
The first important line here is the s:form tag, which specifies the form action; we'll hook this up with a class when we edit struts.xml. The second is the s:radio line. This specifies a human-readable label to be shown next to the radio button; then a name, list, and value, all of which are retrieved from the associated class as follows:
The s:property tag calls getYourEggsAndHam() to get the result returned from the form. (See the previous article in this series for more on the property tag.)
Next, the RadioButton.java file provides the back-end code:
package example;
import java.util.ArrayList; import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
public class RadioButton extends ActionSupport{
private List yesno;
private String yourEggsAndHam;
private static final String YES = "yes";
private static final String NO = "no";
private static final String UNKNOWN = "unknown";
public RadioButton(){
yesno = new ArrayList();
yesno.add(YES);
yesno.add(NO);
yesno.add(UNKNOWN);
}
public String execute() {
return SUCCESS;
}
public String display() {
return NONE;
}
public String getDefaultEggsAndHamValue(){
return UNKNOWN;
}
// getters and setters
public List getYesno() {
return yesno;
}
public void setYesno(List yesno) {
this.yesno = yesno;
}
public String getYourEggsAndHam() {
return yourEggsAndHam;
}
public void setYourEggsAndHam(String yourEggsAndHam) {
this.yourEggsAndHam = yourEggsAndHam;
}
}
Here we've created all the get and set methods to set up both the list of options for the radio button, and to store and access the actual value the user enters. Finally, link the java and jsp file together with these lines in struts.xml:
/form.jsp/radioresult.jsp
Compile RadioButton.java, restart Tomcat, and check out http://localhost:8080/mystruts/radioButtonAction.action. Note that if you try to load form.jsp directly, you'll get an error, because the RadioButton class must be called first to create the yesno list used by the radio button.
All other form tags can be created similarly. For example, to add a "name" text field, first add this line to form.jsp:
Now add this variable and getter/setter methods to RadioButton.java:
private String yourName;
public String getYourName() {
return yourName;
} public void setYourName(String yourName) {
this.yourName = yourName;
}
and this line to radioresult.jsp, to display the name input:
Hi !
Recompile, restart Tomcat, and your form will now load with a textfield for name input.
Struts also provides a handful of non-form tags, which give you other UI options. Let's have a quick look at actionmessage and actionerror. In form.jsp (above), add this section in the header:
and this if tag just before the start of the form section:
This sets up a CSS style to use for the "error" section, then renders the actionerror tag if hasActionErrors() returns true. You'll also need to change the form action to validateUser.
Now to handle the success message. Edit radioresult.jsp to look like this:
Eggs and Ham Results
Do You Like Green Eggs And Ham? :
Again, we've set up a CSS style for action messages, and if there is an action message to display, we display it.
Now we need to add a method to RadioButton.java:
public void validate(){
if("SamIAm".equals(getYourName())) {
addActionMessage("Hello Sam!");
} else {
addActionError("You're not Sam!");
}
}
validate() is automatically called when the form is loaded. Finally, to link it all up, add another action section to struts.xml:
/radioresult.jsp/form.jsp
Now recompile and go to http://localhost:8080/mystruts/validateUser.action. If you put anything but SamIAm into the user name box, you'll get an error message. Otherwise you'll get a purple "Hello Sam!" box at the top of the results page.
One issue to note is that the way this is set up, validate() is called every time the form loads, so you'll always get the "You're Not Sam" error message. To resolve this, you need to rejig the setup to go through a JSP page rather than via validateUser.action. Currently, if you go straight to form.jsp, as discussed above, you'll get an error message because the yesno list won't be populated.
Other non-form tags available are component, which allows you to build a custom UI component; fielderror, which tests for valid field input; and div, which renders an HTML div tag. Struts also supports a selection of AJAX tags for use with the Dojo plugin. For reference on all UI tags, see the Struts documentation.