tohokuaikiのチラシの裏

技術的ネタとか。

ConfluenceのXWorkで、ダウンロードさせるActionを作る

Struts2の記事を参考に。ただ、参考にと言ってもXWorkにはない機能がStruts2にあるので要注意。

atlassian-plugin.xml

resultのtypeにstreamを使用する。こんな感じ。

<result name="success" type="stream">
	<param name="contentType">application/octet-stream</param>
	<param name="inputName">exportZipInputStream</param>
	<param name="bufferSize">1024</param>
	<param name="parse">false</param>
</result>

パラメータについて。

inputName Javaの方でInputStreamを当て込む変数
parse 不明。ただしこれをfalse指定しないとエラーが出てしまった

Actionクラス側

こんな感じ。

    private InputStream exportZipInputStream;

    /**
     * Get the value of exportZipInputStream
     *
     * @return the value of exportZipInputStream
     */
    public InputStream getExportZipInputStream() {
        return exportZipInputStream;
    }
    
    /**
    /**
     * ファイルをダウンロードする
     *
     * @return
     */
    public String download() {
        File zipFile = null;
        String zipFilePath = "foo.zip";

        if (!StringUtils.isEmpty(zipFilePath)) {
            zipFile = new File(zipFilePath);
            if (zipFile.isFile()) {
                try {
                    exportZipInputStream = FileUtils.openInputStream(zipFile);
                    // なぜかaction/result/param@name=contentDisposition が効かないので手動
                    HttpServletResponse response = ServletActionContext.getResponse();
                    response.reset();
                    response.setHeader("Content-Disposition", "attachment;filename="+zipFile.getName()); 
                    response.setContentLength((int) zipFile.length());
                    return SUCCESS;
                } catch (IOException ex) {
                    addActionError(ex.getMessage());
                }
                
            }
        }
        addActionError("error");
        return INPUT;
    }

Struts2だと、Content-DispositionとContent-LengthはActionプロパティを振ってやればStruts.xmlで使用できるみたいだったけど、ConfluenceのXWorkでは効かなかったので、生のResponseを捕まえてHeaderをセットしてやった。