19 - Results and Result Types in Struts 2

Introduction:

  • This chapter will introduce you to all the results and its types used in Struts 2 web application development.

Results and Result Types:

  • The structure of struts.xml for all the web application of struts 2 is:
<!DOCTYPE>
<struts>
   <package name = “name of package” extends = “super package name”>
      <action name = “name of click action” class = “action class to be executed”>
         <result name = “name of result”> path of page to be redirected </result>
     </action>
   </package>
</struts>
  • As we can see above, the result tag is responsible for redirecting to the destination page which can be specified between the <result> elements together with the name of result (that is, type of result).
  • After executing the action class, the target view page will be executed based on the configuration in xml file. That is, after the execution of business logic, the result tag is executed.
  • For example, if the action method is to authenticate a user, there are three possible situations such as: successful login or unsuccessful login attempt or if the user tries to enter invalid login credentials for more number of times, the account gets locked.
  • The result name actually refers to the type of result which can be categorized in nine types which can are described in figure below.
  • There are some predefined result types also which are returned by the action class and compared here as string data type.
    1. String SUCCESS = “success”
    2. String NONE = “none”
    3. String ERROR = “error”
    4. String INPUT = “input”
    5. String LOGIN = “loign”
  • Also, multiple results can be configured with in a single action element wherein, we can compare the returned string values from action class.
  • For example, multiple results can be given as:
<!DOCTYPE>
<struts>

    <package name = “name of package” extends = “super package name”>

       <action name = “name of click action” class = “action class to be executed”>
         <result name = “error”> Errorpage.jsp</result>
         <result name = “none”> Mainpage.jsp</result>
         <result name = “input”> Inputpage.jsp</result>
         <result name= “*”> Otherpage.jsp</result>
      </action>
    </package>
</struts>
  • The user defined result types can be categorized as follows:

 

 

  1. Dispatcher Result:

  • The dispatcher result is used to include or forward to a target view page (JSP). It is default result type in Struts2 framework.
  • It uses RequestDispatcher interface to achieve it, where the target Server or JSP receive the same request and response either using forward() or include() method.
  • The example of Dispatcher result is as follows:
// first.jsp
<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib  uri = "/struts-tags" prefix = "s" %>
<!DOCTYPE html>
<html>
   <head>
    <META HTTP-EQUIV = "refresh" CONTENT ="2;URL=DispatcherAction.action">
    <title>Struts2 Dispatcher Result</title>
   </head>
   <body>
    <br/>
    <h1>
       As the meta tag is set to 2 seconds, you will be redirected to the next page in 2 seconds..
    </h1>
   </body>
</html>

 

// req_disp.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;

  public class  req_disp extends ActionSupport implements ServletRequestAware {
     HttpServletRequest request;
     String message;

     public void setServletRequest(HttpServletRequest request) {
       this.request = request;
     }

     // getter and setter method of message
     public void setMessage(String message){
       this.message = message;
     }

     public String getMessage(){
      return message;
     }

     public String execute() throws Exception{

        setMessage("Example of DispatcherResult in Struts2");
        request.setAttribute("name", "ABC");
        request.setAttribute("address", "Address of ABC");
        return SUCCESS;
     }
  }

 

// next.jsp
<%-- 
    Document   : next
    Created on : Nov 14, 2014, 1:19:42 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib prefix = "s" uri = "/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
   <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">
   <title>JSP Page</title>
  </head>
  <body>
      <h1> 
      <hr/>
         Name : <s:property value = "#request.name" default = "Not Set"/><br>
         Message : <s:property value = "message" default = "Not Set"/><br>
         Address : <s:property value = "#request.address" default = "Not Set"/><br>
     </h1>
  </body>
</html>

 

// struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "devMode" value = "true" />
   <package name = "default" extends = "struts-default">
     <action name = "DispatcherAction" class = "jsp_action.req_disp">
       <result name = "success" type = "dispatcher"> jsp/next.jsp</result>
     </action>
   </package>
</struts>

 

2. Chain Action Result:

  • It is used to achieve action chaining. In the action chaining the multiple actions can be executed in defined sequence. And the target view page will be displayed after last action. In the chain result type, the target resource will be any action which is already configured in struts.xml file.
  • It resembles the chain interceptor of previous chapter.
  • The example is shown below:
// first.jsp

<%-- 
    Document   : first
    Created on : Nov 14, 2014, 12:49:46 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib  uri = "/struts-tags" prefix = "s" %>
<!DOCTYPE html>
  <html>
    <head>
       <META HTTP-EQUIV = "refresh" CONTENT = "2;URL=ChainAction.action">
       <title>Struts2 Chain Result</title>
    </head>
    <body>
       <h1>
         After 2 seconds the page will automatically get refreshed and redirected to the next page..
      </h1>
    </body>
</html>

 

// next.jsp

<%-- 
    Document   : next
    Created on : Nov 14, 2014, 1:19:42 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib prefix = "s" uri = "/struts-tags" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
      <h1> 
        <hr/>
        Message : <s:property value = "message" default = "Not Set"/><br>
        Name : <s:property value = "#request.name" default = "Not Set"/><br>
        Address : <s:property value = "#request.address" default = "Not Set"/><br>
        Company : <s:property value = "#request.company" default = "Not Set"/><br>
        Department : <s:property value = "#request.dept" default = "Not Set"/><br>
      </h1><hr>
         <a href = "first.jsp">Try Again</a>
    </body>
</html>

 

// req_disp.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;

public class req_disp extends ActionSupport implements ServletRequestAware{
   HttpServletRequest request;
   String message;

   public void setServletRequest(HttpServletRequest request) {
      this.request = request;
   }
   public String getMessage(){
      return message;
   }
   public void setMessage(String message)
   {
      this.message = message;
   }

   public String execute() throws Exception {
   setMessage("Chain Action Example in Struts2");
   request.setAttribute("name", "ABC");
   request.setAttribute("address", "AddressLines");
   return SUCCESS;
   }
}

 

// ChainAction.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;

  public class ChainAction extends ActionSupport implements ServletRequestAware{
      HttpServletRequest request;

      public void setServletRequest(HttpServletRequest request) {
      this.request = request;
      }

      public String execute() throws Exception {
        request.setAttribute("company", "My Company");
        request.setAttribute("dept", "Information Technology");
        return SUCCESS;
      }
}

 

// struts.xml

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

<struts>
   <constant name = "devMode" value = "true" />
   <package name = "default" extends = "struts-default">
     <action name = "click" class = "jsp_action.emirp_check">
        <result name = "success" type = "dispatcher">jsp/next.jsp</result>
     </action>
     <action name = "ChainAction" class = "jsp_action.ChainAction">
       <result name = "success" type = "chain">click</result>
     </action>
   </package>
</struts>

3. FreeMarker Result:

  • It is used to integrate the Freemarker templates in the view page. The Freemarker engine renders the freemarker view page and extension will be .ftl of view page.
// first.jsp

<%-- 
    Document   : first
    Created on : Nov 14, 2014, 12:49:46 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib  uri = "/struts-tags" prefix = "s" %>
<!DOCTYPE html>
  <html>
    <body>
      <h2>Struts2 Freemarker result example</h2>
      <hr/>
      <s:form action = "FreemarkerAction" method = "post"> <br/>
         <s:textfield label = "Enter employee Code" name = "code"/> <br/>
         <s:textfield label = "Enter employee Name" name = "name"/> <br/>
         <s:textfield label = "Enter employee City" name = "city"/> <br/>
         <s:textfield label = "Enter employee Salary" name = "salary"/> <br/>
         <s:submit label = "Submit"/> <br/>
         <s:reset label = "Reset"/> <br/>
      </s:form>
    </body>
  </html>

 

// actionclass.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;

   public class actionclass extends ActionSupport{
      private String code, name, city;
      private double salary;

      public String getCode()
      {
        return code;
      }
      public String getName()
     {
       return name;
     }
      public String getCity()
     {
       return city;
     }

      public void setName(String name)
     {
       this.name = name;
     }
     public void setCity(String city)
     {
      this.city = city;
     }
     public void setCode(String code)
     {
     this.code = code;
     } 

    public String execute() throws Exception 
    {
    return SUCCESS;
    }
}

 

// next.jsp

<%-- 
    Document   : next
    Created on : Nov 14, 2014, 1:19:42 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib prefix = "s" uri = "/struts-tags" %>

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
         <h1> 
          <hr/>
          Message : <s:property value = "message" default = "Not Set"/><br>
          Name : <s:property value = "#request.name" default = "Not Set"/><br>
          Code : <s:property value = "#request.code" default = "Not Set"/><br>
          City : <s:property value = "#request.city" default = "Not Set"/><br>
          Salary : <s:property value = "#request.salary" default = "Not Set"/><br>
       </h1>
          <hr>
          <a href = "first.jsp">Try Again</a>
     </body>
</html>

 

//freemarker.ftl

<%@ taglib uri = "/struts-tags" prefix = "s"%>
<html>
  <body>
    <h2>
       Freemarker Page <br>
       <hr>
      <#if Request.code?exists>
        <p> Code : <b> ${Request.code} </b>
      </#if>
      <#if Request.name?exists>
        <p> Name : <b> ${Request.name} </b>
      </#if>
      <#if Request.city?exists>
       <p> City : <b> ${Request.city} </b>
      </#if>
      <#if Request.salary?exists>
        <p> Name : <b> ${Request.salary} </b>
      </#if>

   </h2>
   <hr>
     <a href = "first.jsp">Try Again</a>
  </body>
</html>

 

4. Redirect Result:

  • The redirect result is used to redirect the browser request to the new resource. It works based on HttpServletResponse.sendRedirect() method. It is redirected by browser and the target resource can be part of the same application or cannot be part of the same application. That is, the resource should be apart from the application resources. 
<%-- 
    Document   : first
    Created on : Nov 14, 2014, 12:49:46 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib  uri = "/struts-tags" prefix = "s" %>
<!DOCTYPE html>
<html>
  <head>
    <META HTTP-EQUIV = "refresh" CONTENT = "2;URL = Redirect.action">
    <title> Struts2 Redirect Result Example </title>
  </head>
  <body>
    <h1>
       The content will be refreshed after 2 seconds. 
    </h1>    
  </body>
</html>

 

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;

public class Redirect extends ActionSupport implements ServletRequestAware {
  HttpServletRequest request;
  String message;
  public void setServletRequest(HttpServletRequest request) {
    this.request = request;    
  }

  public String getMessage()
  {
      return message;
  }
  public void setMessage (String message)
  {
      this.message = message;
  }
  public String execute() throws Exception {
    setMessage("Redirect Result example in  Struts2");    
    request.setAttribute("name", "ABC");
    request.setAttribute("address", "AddressLines");
    return SUCCESS;
  }
}

 

// next.jsp

<%-- 
    Document   : next
    Created on : Nov 14, 2014, 1:19:42 PM
    Author     : Infinity
--%>

<%@page contentType = "text/html" pageEncoding = "UTF-8"%>
<%@taglib prefix = "s" uri = "/struts-tags" %>
<!DOCTYPE html>
<html>
  <body>
    <h2>
     Struts2 redirect result example <br>
     <hr>
     Message : <s:property value = "message" default = "Not Set"/><br>
     Name : <s:property value = "#request.name" default = "Not Set"/><br>
     Address : <s:property value = "#request.address" default = "Not Set"/><br>
    </h2>
    <hr>
     <a href = "first.jsp">Try Again</a>
  </body>
</html>

 

// struts.xml

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

<struts>
  <constant name = "devMode" value = "true" />
  <package name = "default" extends = "struts-default">
    <action name = "Redirect" class = "jsp_action.Redirect">
      <result name = "success" type = "redirect"> next.jsp </result>
    </action>
  </package>
</struts>

 

5. Redirect Action

  • Redirect action is same as redirect result type. But here, the target result must be an action either in same application or in the other application. It can be used for both the purposes.

6. Stream Result

  • Streaming refers to input stream and output stream classes in java.
  • It is used to Streaming the InputStream back to the client and client can download the content in the specified format. This is very useful for allowing users to download content from our web application in any format, for example, pdf, doc, xls etc.
  • In our example, we allow user to download and save content in pdf format.
  • For converting data to pdf format following jar files are required:
    1. itext-pdfa-5.3.5.jar
    2. itext-xtra-5.3.5.jar
    3. itextpdf-5.3.5.jar
// first.jsp

<html>
  <head>
    <META HTTP-EQUIV = "refresh" CONTENT = "2;URL = EmployeeResult.action">
    <title> Struts2 Stream Result </title>
  </head>
  <body>
  </body>
</html>

 

// Employee.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;

public class Employee extends ActionSupport implements ServletRequestAware{

   private String id, name, designation, department;
   // default constructor
   public Employee() 
   {
   }
   // parameterized constructor
   public Employee(String id, String name, String designation, String department) 
   {
     this.id = id;
     this.name = name;
     this.designation = designation;
     this.department = department;
    }

    public void setName(String name)
    {
      this.name = name;
    }
    public void setId(String id)
    {
      this.id = id;
    }
    public void setDesignation (String designation)
    {
      this.designation = designation;
    }
    public void setDepartment (String department)
    {
      this.department = department;
    }
    public String getName()
    {
      return name;
    }
    public String getId()
    {
      return id;
    }
    public String getDesignation()
    {
      return designation;
    }
    public String getDepartment()
    {
      return department;
    }
    @Override
    public String toString() 
    {
      return id + "\t" + name + "\t" + designation + "\t" + department;
    }
}

 

// Employee_income.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jsp_action;

public class Employee_income{
  private String month;
  private double basic;
  // default constructor
  public Employee_income(){
  }
  // parameterized constructor
  public Employee_income(String month, double basic){
    this.month = month;
    this.basic = basic;
  }

  public String getMonth()
  {
    return month;
  }
  public double getBasic()
  {
    return basic;
  }
  public void setBasic(double basic)
  {
    this.basic = basic;
  }
  public void setMonth(String month)
  {
    this.month = month;
  }
  @Override
  public String toString() 
  {
    return month + "\t" + basic;
  }
}

 

// Employee_action.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class Employee_action extends ActionSupport implements Preparable{
  Employee emp;
  ArrayList<EmployeeIncome> list;
  private InputStream inputStream;

  @Override
  public void prepare() throws Exception 
  {
    Emp = new Employee("CE001", "AAA BBB", "Sr. Software Engineer", "Information Technology");
    list = new ArrayList<EmployeeIncome>();

    list.add(new EmployeeIncome("January", 20000.0));
    list.add(new EmployeeIncome("February", 21000.0));
    list.add(new EmployeeIncome("March", 20200.0));
    list.add(new EmployeeIncome("April", 20700.0));
    list.add(new EmployeeIncome("May", 20300.0));
    list.add(new EmployeeIncome("June", 20900.0));
  }

  public void setInputStream(InputStream inputStream) {
    this.inputStream = inputStream;
  }

  public String execute() throws Exception {
  // to generate pdf
  ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  Document document = new Document();
  PdfWriter.getInstance(document, buffer);

    public InputStream getInputStream() {
      return inputStream;
    }

    document.open();
    Paragraph p = new Paragraph();
    p.add("Employee income Report");
    try {
         System.out.println(emp);
         p.add("\n Employee Id : " + emp.getId());
         p.add("\n Name : " + emp.getName());
         p.add("\n Role : " + emp.getDesignation());
         p.add("\n Department : " + emp.getDepartment());
        } catch (Exception e) {
             e.printStackTrace();
        }
    p.add("\nMonth Basic HRA PF Allowence NetPay");
    for (EmployeeIncome emp1:list)
    {
       double hra = emp1.getBasic()*.5;
       double pf = emp1.getBasic()*.12;
       double allowence = emp1.getBasic()*.2;
       double netpay = (emp1.getBasic()+hra+allowence)-pf;
       p.add("\n" + emp1.getMonth() + " " + emp1.getBasic()+ " "
       + hra + " " + pf+" "+allowence+" "+netpay);
     }
    p.add("\n Thanks Techmyguru.com");
    document.add(p);
    document.close();
    inputStream = new ByteArrayInputStream(buffer.toByteArray());
    return SUCCESS;
    }    
}

 

// struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
   <constant name = "devMode" value = "true" />
   <package name = "default" extends = "struts-default">
    <action name = "EmployeeResult" class = “results.EmployeeAction">
     <result name = "success" type="stream">
       <param name = "inputName"> inputStream </param>
       <param name = "contentType"> application/pdf </param>
       <param name = "contentDisposition"> attachment;filename = "IncomeStatement.pdf" </param>
       <param name = "bufferSize"> 1024 </param>
     </result>
    </action>
   </package>
</struts>

    Like us on Facebook