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 }