I¹m seeing a really strange issue in one of our struts apps with a stream result where the downloaded file is empty (zero bytes).
I can¹t see where it is going wrong. I dynamically generate a zip file in tomcat¹s temp folder and then use a Buffered input reader to pass off to the struts stream. I can the the zip file in the tomcat temp folder and it contains the data it¹s supposed to. The issue is getting from the file to the input stream. I¹ve included by struts configuration, the relevant part of my action and the a detailed log. I¹d appreciate any help. Z. My struts config : <action name="exportData" class="clientAction" method="exportData"> <result name="success" type="stream"> <param name="allowCaching">false</param> <param name="contentType">${documentContentType}</param> <param name="contentDisposition">${documentFileName}</param> <param name="contentLength">${documentContentLength}</param> <param name="bufferSize">1024</param> </result> </action> In my action class : String filePrefix = System.getProperty("java.io.tmpdir") + ³/temporaryData.zip" ; LOGGER.debug("Read the generated file : "+ zipName); File tempFile = new File(zipName); if(tempFile.exists()){ LOGGER.debug("The file exists : "+ zipName); } if(tempFile.canRead()){ LOGGER.debug("The file can be read : "+ zipName); } if(tempFile.isFile()){ LOGGER.debug("The file is a file : "+ zipName); } if(tempFile.isHidden()){ LOGGER.debug("The file is hidden : "+ zipName); } LOGGER.debug("The file size is : "+ tempFile.length()); inputStream = new BufferedInputStream(new FileInputStream(tempFile)); documentFileName = "attachment; filename=NfcData.zip"; documentContentType = "application/zip"; My log files looks like this: DEBUG [http-bio-8084-exec-24] - Zip file name : /Users/zoran/Library/Application Support/NetBeans/7.4/apache-tomcat-7.0.41.0_base/temp/temporaryData.zip DEBUG [http-bio-8084-exec-24] - Read the generated file : /Users/zoran/Library/Application Support/NetBeans/7.4/apache-tomcat-7.0.41.0_base/temp/temporaryData.zip DEBUG [http-bio-8084-exec-24] - The file exists : /Users/zoran/Library/Application Support/NetBeans/7.4/apache-tomcat-7.0.41.0_base/temp/temporaryData.zip DEBUG [http-bio-8084-exec-24] - The file can be read : /Users/zoran/Library/Application Support/NetBeans/7.4/apache-tomcat-7.0.41.0_base/temp/temporaryData.zip DEBUG [http-bio-8084-exec-24] - The file is a file : /Users/zoran/Library/Application Support/NetBeans/7.4/apache-tomcat-7.0.41.0_base/temp/temporaryData.zip DEBUG [http-bio-8084-exec-24] - The file size is : 1441 DEBUG [http-bio-8084-exec-24] - Document File name : attachment; filename=NfcData.zip Document Content Type : application/zip DEBUG [http-bio-8084-exec-24] - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class org.apache.struts2.dispatcher.StreamResult] and property [allowCaching] DEBUG [http-bio-8084-exec-24] - Converter is null for property [allowCaching]. Mapping size [0]: DEBUG [http-bio-8084-exec-24] - field-level type converter for property [allowCaching] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [allowCaching] = com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482 DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class org.apache.struts2.dispatcher.StreamResult] and property [bufferSize] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [bufferSize] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [bufferSize] = com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482 DEBUG [http-bio-8084-exec-24] - Creating converter of type [com.opensymphony.xwork2.conversion.impl.NumberConverter] DEBUG [http-bio-8084-exec-24] - Entering nullPropertyValue [target=[com.sparecreative.sms.gateway.action.ClientAction@988c0a6, com.opensymphony.xwork2.DefaultTextProvider@907a831], property=contentDisposition] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.opensymphony.xwork2.util.CompoundRoot] and property [(null)] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Entering nullPropertyValue [target=[com.sparecreative.sms.gateway.action.ClientAction@988c0a6, com.opensymphony.xwork2.DefaultTextProvider@907a831], property=contentType] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.opensymphony.xwork2.util.CompoundRoot] and property [(null)] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Entering nullPropertyValue [target=[com.sparecreative.sms.gateway.action.ClientAction@988c0a6, com.opensymphony.xwork2.DefaultTextProvider@907a831], property=inputName] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.opensymphony.xwork2.util.CompoundRoot] and property [(null)] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Entering nullPropertyValue [target=[com.sparecreative.sms.gateway.action.ClientAction@988c0a6, com.opensymphony.xwork2.DefaultTextProvider@907a831], property=contentLength] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.opensymphony.xwork2.util.CompoundRoot] and property [(null)] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Entering nullPropertyValue [target=[com.sparecreative.sms.gateway.action.ClientAction@988c0a6, com.opensymphony.xwork2.DefaultTextProvider@907a831], property=bufferSize] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.opensymphony.xwork2.util.CompoundRoot] and property [(null)] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Entering nullPropertyValue [target=[com.sparecreative.sms.gateway.action.ClientAction@988c0a6, com.opensymphony.xwork2.DefaultTextProvider@907a831], property=contentCharSet] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.opensymphony.xwork2.util.CompoundRoot] and property [(null)] DEBUG [http-bio-8084-exec-24] - field-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - global-level type converter for property [null] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.sparecreative.sms.gateway.action.ClientAction] and property [documentContentLength] DEBUG [http-bio-8084-exec-24] - Converter is null for property [documentContentLength]. Mapping size [0]: DEBUG [http-bio-8084-exec-24] - field-level type converter for property [documentContentLength] = none found DEBUG [http-bio-8084-exec-24] - Retrieving convert for class [class com.sparecreative.sms.gateway.action.ClientAction] and property [documentContentLength.documentContentLength] DEBUG [http-bio-8084-exec-24] - global-level type converter for property [documentContentLength] = none found DEBUG [http-bio-8084-exec-24] - falling back to default type converter [com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter@5b6e6482] DEBUG [http-bio-8084-exec-24] - Creating converter of type [com.opensymphony.xwork2.conversion.impl.StringConverter] DEBUG [http-bio-8084-exec-24] - Streaming result [inputStream] type=[${documentContentType}] length=[${documentContentLength}] content-disposition=[${documentFileName}] charset=[null] DEBUG [http-bio-8084-exec-24] - Streaming to output buffer +++ START +++ DEBUG [http-bio-8084-exec-24] - Streaming to output buffer +++ END +++ DEBUG [http-bio-8084-exec-24] - after Locale=en_AU DEBUG [http-bio-8084-exec-24] - intercept }