在IBM WP 6.1.5上使用JSR 286,Struts 2.2.0 + PortletPlugin 2.2.0下载文件pfrom portal

时间:2011-01-25 20:33:58

标签: struts2 download websphere-portal jsr286

我正在使用JSR-286 + Struts 2.2.0 + PortletPlugin 2.2.0

我无法为用户想要下载的文件设置名称。 用户可以获取文件,但它的名称已损坏。而不是“myImage.png”用户获取“241883e9”或“241563a2”。 如果用户重命名下载的文件并打开它,他可以看到文件没有损坏。请看我的代码:

文件-listing.jsp:

<li onclick="goToAction('<s:url action="downloadattachement" portletUrlType="resource" />', {'attachementId':<s:property value="id" />}, 'POST')"><s:property value="name"/></li>

函数“goToAction”动态生成并提交它(我已经尝试了两种:POST和GET,它没有帮助。):

<form action="/wps/myportal/!VERY_LONG_PORTAL_URL_GOES_HERE/" method="POST" id="actionUrlTemporaryForm1295987206509"> <input type="hidden" name="attachementId" value="2" /> </form>

我的struts xml配置文件:

<!-- 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>

动作代码:

@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";
    }

我从未在日志文件中看到过这个LOG行: LOG.trace(“#getFileName {}”,attachement.getName());

但我明白了

[25.01.11 23:26:46:582 MSK] 00000052 srt W com.ibm.ws.webcontainer.srt.SRTServletResponse setHeader警告:无法设置标头。 RESP 已经承诺了。

似乎我无法为响应设置标头...... :(

我做错了什么?请帮忙。

UPD:我找到了部分解决方案: 我已将此代码添加到我的操作中:

PortletActionContext.getResponse().setProperty("content-Disposition", "attachment;filename=\""+attachement.getName()+"\"");                     
PortletActionContext.getResponse().setProperty("content-Type", attachement.getMimeType());

现在的问题是文件名:如果它包含非ascii char文件名已损坏。 文件名如:“my file.doc”,“02.png”工作正常。

1 个答案:

答案 0 :(得分:1)

问题出在result type =“stream”以及“Content-disposition”标题的filename属性值中。 对于FF,我使用了ISO-8859-1,对于IE6-8,我使用了url-encoding。 我已经使用user-agent标头来确定浏览器。我的解决方案只有一个问题,但对我来说这是可以接受的:IE8用下划线替换文件名中的空格。例如 “my fav image.png”将是“my_fav_image.png”,是IE8。 FF确实取消了HTTP的默认编码,并且不会尝试破坏文件名属性值。 您可以在StackOverflow上找到更多信息。