Struts 2 Action Error and Action Message

Filed Under: Struts 2

Struts 2 provide a lot of custom tags for development and we have already looked into Data Tags, Control Tags and UI Tags. Today we will look into two tags that are related to action class response that we can use in the result pages.

Struts 2 Action Error and Action Message

  1. actionerror tag: This tag is used in conjunction with Action class validation for form fields. If validation fails for any form fields, we can add action errors and then Struts 2 API forwards the request to “input” result page where we can use this tag to show the error messages. This tag is helpful in server side validation of form fields and then returning the input page with error message. Syntax of this tag is:

    <s:actionerror/>

    We will look it’s usage with a simple project to explain how easy s:actionerror is to use.

  2. actionmessage tag: This tag is used to show some custom message added by Action classes in the result page. For example, we can use this tag to welcome a user and show them last login time at the top of the page. Syntax of this tag is:

    <s:actionmessage/>

Both these tags generated an unordered list of action errors or messages added in the action class. Let’s create a simple project to show their usage. Our final project will look like below image.

Struts 2 Action Error Message Example

Struts 2 Configuration Files

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Struts2ActionErrorMessages</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Struts2ActionErrorMessages</groupId>
	<artifactId>Struts2ActionErrorMessages</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.15.1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

struts.xml


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- constant to define result path locations to project root directory -->
	<constant name="struts.convention.result.path" value="/"></constant>
	<!-- constant to define global properties file for i18n messages -->
	<constant name="struts.custom.i18n.resources" value="global"></constant>
	
	<package name="user" namespace="/" extends="struts-default">
		<action name="login">
			<result>/login.jsp</result>
		</action>
		<action name="Welcome" class="com.journaldev.struts2.actions.WelcomeAction">
			<result name="success">/welcome.jsp</result>
			<result name="input">/login.jsp</result>
		</action>
	</package>

</struts>

Configuration files are self understood and used to configure maven web application project to use Struts2 framework. The important point to note is the struts.custom.i18n.resources where we are providing property file name for global messages. We will use this file for labels in result pages for internationalization.

Another point to notice is the “input” result page for Welcome action, it’s used incase of any form field validation failure.

global.properties


#global messages
msg.welcome=Hi
label.username=User Name
label.password=Password
label.submit.login=Login

#error messages
error.username.required=User Name is required field
error.password.required=Password is required field

A simple property file that will be used in result pages for labels.

Struts 2 Action Class

WelcomeAction.java


package com.journaldev.struts2.actions;

import com.opensymphony.xwork2.ActionSupport;

public class WelcomeAction extends ActionSupport {

	@Override
	public String execute() {
		return SUCCESS;
	}

	@Override
	public void validate() {
		if("pankaj".equalsIgnoreCase(getUsername()) && "admin".equalsIgnoreCase(getPassword())){
			addActionMessage("Welcome Admin, do some work.");
		}else{
			if(!"pankaj".equalsIgnoreCase(getUsername())){
				addActionError("User name is not valid");
			}
			if(!"admin".equalsIgnoreCase(getPassword())){
				addActionError("Password is wrong");
			}
		}
	}

	// java bean properties
	private String username;
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

We are extending ActionSupport class and overriding validate method where we are adding action errors and action messages to ValueStack. Other part of action classes include execute() method and java bean properties with getter setter methods.

Struts 2 Result Pages

login.jsp


<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Login Page</title>
<!-- Adding CSS for Styling of error messages -->
<style type="text/css">
.errorDiv{
	background-color:gray;
	border:1px solid black;
	width:400px;
	margin-bottom:8px;
}
</style>
</head>
<body>
<h3>Struts2 ActionError Example</h3>

<%-- hasActionErrors() method is defined in ActionSupport --%>
<s:if test="hasActionErrors()">
	<div class="errorDiv">
		<s:actionerror/>
	</div>
</s:if>

<s:form action="Welcome">
<s:textfield name="username" key="label.username"></s:textfield>
<s:password name="password" key="label.password"></s:password>
<s:submit key="label.submit.login" align="center" name="submit"></s:submit>
</s:form>
</body>
</html>

We are using Struts2 if conditional tag to check if there are any action error messages are present or not. hasActionErrors() method is defined in ActionSupport class that returns true if any action errors exists in the ValueStack.

Notice that we are using CSS for styling of error messages and using key attributes of UI tags to generate the label from property file configured in struts configuration file. We are not using actionmessage tag here because if validation doesn’t fail, we are not returning to this page.

welcome.jsp


<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Welcome Page</title>
<style type="text/css">
.welcome {
	background-color:green;
	border:1px solid black;
	width:400px;
}
//ul.actionMessage is added by Struts2 API 
ul.actionMessage li {
	color:yellow;
}
</style>

</head>
<body>
<h3>Struts2 ActionMessage Example</h3>
<s:if test="hasActionMessages()">
   <div class="welcome">
      <s:actionmessage/>
   </div>
</s:if>
<br><br>
<s:property value="getText('msg.welcome')" /> <s:property value="username"/>
</body>
</html>

A simple result page where we are utilizing actionmessage tag. Since this tag generates list with class name as actionMessage, we can use it for styling purpose. hasActionMessages() method is defined in ActionSupport class and returns true if there are any action messages present.

When we run above application, we get following response pages.

Struts 2 ActionError example

Generated HTML snippet of actionerror tag is:


<ul class="errorMessage">
            <li><span>User name is not valid</span></li>
            <li><span>Password is wrong</span></li>
</ul>

Struts 2 ActionMessage Example

Generated HTML snippet of actionmessage tag is:


<ul class="actionMessage">
        <li><span>Welcome Admin, do some work.</span></li>
</ul>

As you can see it’s very easy to use action errors and action messages tags in result pages and since generated html contains class for tags, we can easily add CSS rules for specific styling purposes. Download project from below link and play around with it for better understanding.

Comments

  1. shar says:

    Thanks pankaj!
    your post helped me.

    1. shar says:

      Btw, Is there a way to remove the bullet before the ActionMessage while displaying on .jsp?
      Thanks

  2. Cherukuri says:

    Hi Pankaj,

    Your Tutorials are good. I think When you started learning you must have followed Mkyong.com ..because i see some resemblance in your posts 🙂

  3. kamal says:

    Hi Pankaj,

    Great Work and thanks for explaining things. I’m a new programmer in Struts and need 1 help. In case we want to create custom validator which involves 2 fields simultaneously such as lets consider that we have 3 fields in our form and we want to validate if field-1 is the sum of field-2 and field-3 . Then there are three conditions first field-1 =field-2, field-1 =field-3, field-1 =field-2+field-3. How can we achieve that as it involves integers and also validation on 2 fields using same validation.

  4. ramesh says:

    /login.jsp
    Could u explain tis?

  5. Deepesh says:

    Please reply to my question as early as possible.

  6. Deepesh says:

    What should I do if I want to override “errorMessage” class? I mean, if I don’t want that and , what should I do? Expect a quick replay. Thanks

    1. Pankaj says:

      Which class you are talking about, could you please mention that clearly?

      1. Deepesh says:

        I have got a fielderror response from struts validation framework like this.

        Username is invalid.

        But unfortunately, this , and elements in the response message breaks my page alignment. I just want to know how I could avoid these tags(, and ) from the response message.

        Thanks in advance.

      2. Deepesh says:

        I have got a fielderror response from struts validation framework like this.

        Username is invalid.


        But unfortunately, this , and elements in the response message breaks my page alignment. I just want to know how I could avoid these above said tags from the response message.

        Thanks in advance.

        1. Deepesh says:

          I have got a fielderror response from struts validation framework like this.

          ul class=”errorMessage”
          li
          span Username is invalid./span
          /li
          /ul

          (Sorry, I,m not able to write html codes here. That’s why I avoid angular brackets of html tags. )

          But unfortunately, this , and elements in the response message breaks my page alignment. I just want to know how I could avoid these above said tags from the response message.

          Thanks in advance.

          1. Pankaj says:

            You can write CSS code for class “errorMessage” and fix the alignment. I am not sure how to avoid them.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages