File download in Struts 2
hibernate, java, jsp, spring, struts2
Solution
Alright, change `inputName` to `inputStream`. Like this
private InputStream inputStream;
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream= inputStream;
}
the default setting for the parameter `inputName` is `inputStream`, so, you could remove that. Also note that parameter's names in result are looked up in the value stack. So, if you expose a getter like `getInputName` in the action means that you want to override the value in the configuration.
Problem
I am trying to download a file from my web server running Struts2, Hibernate and Spring but I am always getting this exception. ``` java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [inputName] in the invocation stack. Check the <param name="inputName"> tag specified for this action. org.apache.struts2.dispatcher.StreamResult.doExecute(StreamResult.java:237) org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186) com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275) org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265) org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:249) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:249) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:139) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) com.riteshsangwan.ossoc.core.interceptors.AuthenticationInterceptor.intercept(AuthenticationInterceptor.java:34) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562) org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99) ``` I have checked the `inputName` parameter and debugged the project to find out that `InputStream` is not `null`. This is the download class: ``` inputName= new ByteArrayInputStream(mf.getFileContent()); ``` and this is Struts 2 mapping: ``` <action name="downloadfile" class="com.riteshsangwan.ossoc.core.actions.DownloadFile"> <result name="success" type="stream"> <param name="inputName">inputName</param> <param name="contentDisposition">attachment;filename=${fileName}</param> <param name="contentType">${contentType}</param> <param name="bufferSize">1024</param> <param name="contentLength">${contentLength}</param> <param name="allowCaching">false</param> </result> <result name="input">/user/files.jsp</result> </action> ``` Is the exception because of `ByteArrayInputStream` or any other reason. I have public getter and setter method for all variables and I have checked that none of them is `null`. EDIT: `DownloadFile` class: ``` package com.riteshsangwan.ossoc.core.actions; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.riteshsangwan.ossoc.core.dao.FilesBo; import com.riteshsangwan.ossoc.core.entities.Files; import com.riteshsangwan.ossoc.core.entities.Users; import com.riteshsangwan.ossoc.core.util.MyFile; import com.riteshsangwan.ossoc.core.util.Operations; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.ServletContextAware; public class DownloadFile extends ActionSupport implements ServletContextAware{ private long fid; private String contentType; private long contentLength; private String fileName; private InputStream inputName; private ServletContext context; private String downloadStatus; private String downloadpassword; private List fileList; private Map<String,Object> session; public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public List getFileList() { return fileList; } public void setFileList(List fileList) { this.fileList = fileList; } public String getDownloadStatus() { return downloadStatus; } public void setDownloadStatus(String downloadStatus) { this.downloadStatus = downloadStatus; } public String getDownloadpassword() { return downloadpassword; } public void setDownloadpassword(String downloadpassword) { this.downloadpassword = downloadpassword; } public String getStatus() { return downloadStatus; } public void setStatus(String downloadStatus) { this.downloadStatus = downloadStatus; } @Autowired private FilesBo fbo; @Autowired private Operations operation; public Operations getOperation() { return operation; } public void setOperation(Operations operation) { this.operation = operation; } public FilesBo getFbo() { return fbo; } public void setFbo(FilesBo fbo) { this.fbo = fbo; } public long getFid() { return fid; } public void setFid(long fid) { this.fid = fid; } public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } public long getContentLength() { return contentLength; } public void setContentLength(long contentLength) { this.contentLength = contentLength; } public InputStream getInputName() { return inputName; } public void setInputName(InputStream inputName) { this.inputName = inputName; } @Override public String execute(){ String response; int a=10; try { session=ActionContext.getContext().getSession(); Users u= (Users) session.get("user"); long uid=u.getUid(); fileList=fbo.getAllFiles(uid); Files f=getFbo().getFileWithData(getFid()); MyFile mf=new MyFile(); mf.setFileContent(f.getFileData()); mf.setFileContentType(f.getFileContentType()); mf.setFileHash(f.getFileHash()); mf.setFileName(f.getFileName()); mf.setFileSize(f.getFileSize()); mf.setPassword(downloadpassword); mf=operation.decrypt(mf); fileName=mf.getFileName(); contentLength=mf.getFileSize(); contentType=mf.getFileContentType(); inputName=new ByteArrayInputStream(mf.getFileContent()); response=ActionSupport.SUCCESS; } catch(IOException e) { if(e.getMessage().equalsIgnoreCase("Message has been altered or password incorrect")) { downloadStatus="Message has been altered or incorrect password. Try again."; } response=ActionSupport.INPUT; } catch(Exception e) { downloadStatus="Some error occured. Try Again"; response=ActionSupport.INPUT; } return response; } @Override public void setServletContext(ServletContext servletContext) { this.context=servletContext; } } ```