I'm using JSR-286 + Struts 2.2.0 + PortletPlugin 2.2.0
I can't set name for file which user wants to download. User can get file, but it's name is corrupted. Instead of "myImage.png" user gets "241883e9" or "241563a2". If users renames downloaded file and opens it he can see that the file is not corrupted. Please, see my code:
file-listing.jsp:
<li onclick="goToAction('<s:url action="downloadattachement" portletUrlType="resource" />', {'attachementId':<s:property value="id" />}, 'POST')"><s:property value="name"/></li>
function "goToAction" dynamically generates from and submits it (I've tried both: POST and GET, it doesn't help.):
<form action="/wps/myportal/!VERY_LONG_PORTAL_URL_GOES_HERE/" method="POST" id="actionUrlTemporaryForm1295987206509"> <input type="hidden" name="attachementId" value="2" /> </form>
my struts xml config file:
<!-- Download attached file by attachementId -->
<action name="downloadattachement" class="ru.portal.DownloadAttachementAction">
<result name="success" type="stream">
<param name="allowCaching">false</param>
<param name="contentType">${contentType}</param>
<param name="inputName">attachementContents</param>
<param name="contentDisposition">>attachment;filename="${fileName}"</param>
<param name="bufferSize">1024</param>
</result>
</action>
And an action code:
@Override
protected String bareExecute() throws Exception {
String result = Action.SUCCESS;
Attachement attachement = EJBUtil.lookup(IAttachementManager.class).get(attachementId);
LOG.info("Trying to download Attachement[{}]", attachement);
File attachementFile = new File(attachement.getPath());
if(attachementFile.exists()){
attachementContents = new FileInputStream(attachementFile);
}else{
LOG.error("There is no attachement[{}] file here[{}]",attachementId, attachement.getPath());
}
return result;
}
public String getContentType(){
return attachement.getMimeType();
}
public String getFileName(){
LOG.trace("#getFileName {}", attachement.getName());
return attachement.getName();
}
public Integer getAttachementId() {
return attachementId;
}
public void setAttachementId(Integer attachementId) {
this.attachementId = attachementId;
}
public Attachement getAttachement() {
return attachement;
}
public InputStream getAttachementContents() {
return attachementContents;
}
@Override
public String getCurrentActionName() {
return "downloadattachement";
}
I've never seen this LOG line in my log file: LOG.trace("#getFileName {}", attachement.getName());
But I see
[25.01.11 23:26:46:582 MSK] 00000052 srt W com.ibm.ws.webcontainer.srt.SRTServletResponse setHeader WARNING: Cannot set header. Resp onse already committed.
Seems like I can't set headers for response... :(
What do I do wrong? Please help.
UPD: I've found partial solution: I've added this code to my action:
PortletActionContext.getResponse().setProperty("content-Disposition", "attachment;filename=\""+attachement.getName()+"\"");
PortletActionContext.getResponse().setProperty("content-Type", attachement.getMimeType());
The problem is in file name now: if it contains non ascii char file name is corrupted. File names like: "my file.doc", "02.png" work fine.