File Download Example in Struts 2
This tutorial will help you understanding how to create a Struts 2 action class that allows users to download files from server to their local computer.
struts.xml
Struts 2 provides a custom result type called “stream” that performs file download by “streaming” an InputStream of a file to the client through the HttpServletResponse. Here’s an example that shows how to define this result type element in struts.xml:
The struts.xml file should have the following mapping
<struts> <package name="default" namespace="/jsp" extends="struts-default"> <action name="download" class="com.simplecode.action.DownloadAction"> <result name="success" type="stream"> <param name="contentDisposition">attachment;filename=${fileName}</param> <param name="contentType">application/vnd.ms-excel</param> <param name="inputName">fileInputStream</param> <param name="bufferSize">1024</param> </result> </action> </package> </struts>
Note that we declare a property placeholder called “fileName” which will be dynamically updated by Struts. Now in the action class, we need to declare a variable with the same name along with getter and setter method. By this way we have configured the download file name dynamically.
In addition to that, we must define an InputStream object which has the same name as the name specified by the inputName parameter in struts.xml. All the variables must have appropriate getter methods.
Recommended Article
Action Class
package com.simplecode.action; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import com.opensymphony.xwork2.Action; public class DownloadAction implements Action { private InputStream fileInputStream; // Used to set file name dynamically private String fileName; public InputStream getFileInputStream() { return fileInputStream; } public String execute() throws Exception { File fileToDownload = new File("C:/Download/MyFile.xls"); fileName = fileToDownload.getName(); fileInputStream = new FileInputStream(fileToDownload); return SUCCESS; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } }
** UPDATE: Struts 2 Complete tutorial now available here.
Jsp
<%@taglib uri="/struts-tags" prefix="s"%> <html> <title>File Download</title> <body> <h3>Struts 2 file download example</h3> <s:url id="fileDownload" namespace="/jsp" action="download"></s:url> <h4> Download file - <s:a href="%{fileDownload}">MyFile.xls</s:a> </h4> </body> </html>
Related Article
Demo
On running this application
How to override struts 2.x file upload error messages?
In my previous tutorial I have explained about how to upload file in struts 2 web application. This article aims at overriding the default file upload error message which are added by file upload interceptor during file upload validation. These error messages are stored in the struts-messsages.properties file. The values of the messages can be overridden by providing the text for the following keys:
struts.messages.error.uploading - error when uploading of file fails struts.messages.error.file.too.large - error occurs when file size is large struts.messages.error.content.type.not.allowed - when the content type is not allowed struts.messages.error.file.extension.not.allowed - when the file extension is not allowed
** UPDATE: Struts 2 Complete tutorial now available here.
In-order to override these message, you need follow the below steps.
1. Create a global.properties file in the src folder and add the following test to your global.properties file:
struts.messages.error.file.too.large = Uploaded File size is too large struts.messages.error.uploading = File upload failed struts.messages.error.content.type.not.allowed =File type is not allowed. struts.messages.error.file.extension.not.allowed =File extension is not allowed.
2. Add the constant In struts.xml:
<constant name="struts.custom.i18n.resources" value="global" />
After implementing these changes restart the application, and now in case of error in validation you get the custom error message which we have written in the properties file.
Recommended Article
Read More
Struts 2 Dynamic Method Invocation using Action Wildcards
This tutorial is a continuation of previous example ( DispatchAction functionality ). In this example you will see about avoiding configuration of separate action mapping for each method in Action class by using the wildcard method. Look at the following action mapping to under stand the concept.
** UPDATE: Struts 2 Complete tutorial now available here.
Action mapping From previous example
<struts> <package name="default" extends="struts-default"> <action name="Number" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="addNumber" method="add" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="multiplytNumber" method="multiply" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="subtractNumber" method="subtract" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="divideNumber" method="divide" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> </package> </struts>
Action mapping Using Wildcard
<struts> <package name="default" extends="struts-default"> <action name="*Number" method="{1}" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> </package> </struts>
As you can see we have replaced all the method names with an asterisk(*) symbol. The word that matches for the first asterisk will be substituted for the method attribute. So when the request URL is “divideNumber” the divide() method in the CalculatorAction class will be invoked.
Do read :
Note :
1. We can also substitute asterisk in the jsp pages.
For example
<action name="*Number" method="{1}"> <result name="success">/{1}curd.jsp</result> </action>
2. The wild card can be placed in any position in a action name
For example
<action name="Number*" method="{1}"> <result name="success">/{1}curd.jsp</result> </action>
3. You can have multiple wild card , for example
<action name="*Number*" method="{1}"> <result name="success">/{1}curd{2}.jsp</result> </action>
To match first wildcard, we have to use {1}, to match second wild card we have to use {2}.
|
Hope you understand about Action Wildcards uses. Thanks for reading :)
Read More
DispatchAction Functionality in Struts 2
In Struts 1 DispatchAction helps us in grouping a set of related functions into a single action. In Struts 2 all the Actions by default provide this functionality. To use this functionality we need to create different methods with the similar signature of the execute() method.
In our example the CalculatorAction class has all the methods related to a Calculator like add(), multiply(), division() and subtract() which are used for performing mathematical operation on two numbers and it displays the result in a single jsp based on the action button clicked in jsp.
** UPDATE: Struts 2 Complete tutorial now available here.
Action Class
package com.simplecode.action; import com.opensymphony.xwork2.Action; public class CalculatorAction implements Action { private float number1; private float number2; private float result; private String methodName; public String execute() { number1 = 0; number2 = 0; result = 0; setMethodName("execute Method"); return SUCCESS; } public String add() { result=number1+number2; setMethodName("add Method"); return SUCCESS; } public String subtract() { result = number1 - number2; setMethodName("subtract Method"); return SUCCESS; } public String multiply() { result = number1 * number2; setMethodName("multiply Method"); return SUCCESS; } public String divide() { if(number2!=0) result = number1/number2; else if(number1!=0) result = number2/number1; else result=0; setMethodName("divide Method"); return SUCCESS; } public float getNumber1() { return number1; } public void setNumber1(float number1) { this.number1 = number1; } public float getNumber2() { return number2; } public void setNumber2(float number2) { this.number2 = number2; } public float getResult() { return result; } public void setResult(float result) { this.result = result; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } }
Recommended Article
Struts.xml
Here in order to do a DispatchAction functionality we need to create separate action mapping for each method in the action class, which is done in the struts.xml as shown below.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="default" extends="struts-default"> <action name="Number" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="addNumber" method="add" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="multiplytNumber" method="multiply" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="subtractNumber" method="subtract" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> <action name="divideNumber" method="divide" class="com.simplecode.action.CalculatorAction"> <result name="success">/curd.jsp</result> </action> </package> </struts>
Here note that we use the same action class in all the action mappings but only the method name differs. So now When the request URL is “Number” the execute() method in the CalculatorAction class will be executed. When the request URL is “addNumber” the add() method in the CalculatorAction class will be invoked, this is specified using the method attribute of the action tag in struts xml. Similarly for subtract, multiply and divide request the subtract() ,multiply() and divide() methods will be invoked respectively.
This way configuring a separate action mapping for each method of same action class can be avoided by using a feature called Dynamic Method Invocation. We will learn about this in our upcoming tutorial.
Jsp
In the curd.jsp page we create five different buttons to invoke the different methods in the CalculatorAction class.
<%@taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>Dispatch Action</title> </head> <body> <s:form action="Number"> <table> <tr><td><s:textfield name="number1" label="Number 1 " id="number1"/></td></tr> <tr><td><s:textfield name="number2" label="Number 2 " id="number2"/></td></tr> <tr><td><s:textfield name="result" label="Result " readonly="true" /></td></tr> <tr> <td><s:textfield name="methodName" label="Method involked " readonly="true" /></td> </tr> <tr> <td><s:submit action="addNumber" value="Add" align="left"/></td> <td><s:submit action="subtractNumber" value="Subtract" align="left"/></td> <td><s:submit action="divideNumber" value="Divide" align="left"/></td> <td><s:submit action="multiplytNumber" value="Multiply" align="left"/></td> <td><s:submit align="left"/></td> </tr> </table> </s:form> </body> </html>
On running the example the following page will be displayed in the browser. Now when the user click a button the appropriate method in the CalculatorAction class gets invoked.
For example When the user clicks the add button the add() method in the CalculatorAction class gets executed and the following page is displayed.
|
Read More
Difference between Action Chaining & Action redirect in Struts 2
In Struts 2, sometimes you may want to process another action when one action completes. For example on successfully submitting a form you want to render output from other action.
This can be done by two methods
1) Action Chaining
2) Action redirect
** UPDATE: Struts 2 Complete tutorial now available here.
Difference between Action redirect & Action Chaining:
Difference between Action Chaining & Action redirect is, Action Redirect starts from scratch, it is like you called the other action class for the first time while Action Chaining keeps the values of the first Action class on the value stack and adds the variables of the new action. Look at the example below to understand the above concepts.
Action Chaining:
<package name="default" extends="struts-default"> <action name="Register" class="com.simplecode.action.RegisterAction"> <result name="success" type="chain">dbAction</result> </action> <action name="dbAction" class="com.simplecode.action.DataBaseAction"> <result name="success">/success.jsp</result> </action> </package>
Action redirect:
<package name="default" extends="struts-default"> <action name="Register" class="com.simplecode.action.RegisterAction"> <result name="success" type="redirect">dbAction</result> </action> <action name="dbAction" class="com.simplecode.action.DataBaseAction"> <result name="success">/success.jsp</result> </action> </package>
Read More
Login & Logout Example in Struts 2
In this tutorial we will see how to create a simple Struts 2 Login Application. The following files are needed to create a Login Application.
** UPDATE: Struts 2 Complete tutorial now available here.
Final project structure
- Create a New Dynamic Web Project in eclipse and give a name to your project
Action class
file : LoginAction.java
package com.action; public class LoginAction { private String userName; private String password; public String execute() { if (userName.isEmpty() || password.isEmpty()) return "error"; else return "success"; } public String getUserName() { return userName; } public String getPassword() { return password; } public void setUserName(String userName) { this.userName = userName; } public void setPassword(String password) { this.password = password; } }
JSP
File : login.jsp use the Struts 2 tags to display username and password input fields and submit button.
<%@taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>Login</title> </head> <body> <s:form action="login"> <s:textfield name="userName" label="User Name" /> <s:password name="password" label="Password" /> <s:submit value="Submit" /> </s:form> </body> </html>
file : success.jsp : A JSP view page to display a welcome message to user.
<%@taglib uri="/struts-tags" prefix="s"%> <html> <head> <title>Welcome</title> <s:head /> </head> <body> <h4> Welcome <s:property value="userName" /> , you are logged in successfully </h4> </body> </html>
file :error.jsp : A JSP view page to display error message when a wrong user id and password is entered
<html> <head> <title>Un Authorised</title> </head> <body> <h1>Login failed</h1> </body> </html>
Struts configuration file
The configuration in struts.xml should be as shown below
<struts> <package name="default" extends="struts-default"> <action name="login" class="com.action.LoginAction"> <result name="success">success.jsp</result> <result name="error">error.jsp</result> </action> </package> </struts>
web.xml
Make sure you have done the mapping properly in web.xml file as shown below
<web-app> <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> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
Demo
Now on running this application in TomCat server, the application will deliver the JSP as below
http://localhost:8089/Struts2Login/
** Update – The below screen shot is the demo of Tab Style Login and Signup feature using jQuery in Java web application, read the article here to learn about the same