JavaのWebアプリケーション開発フレームワークによる、Webサイト開発の顛末記です。

EclipseのMavenを使った、Spring-MVC、Thymeleaf、MyBatis 等のプログラミングテクニックを、
備忘録的に記録しています。実際に動くソースコードを多用して説明していますので、
これからEclipseや、Spring-MVCを始めたいと思っている人にとって、少しでも参考になれば幸いです。
Spring-MVCの散歩道 > 応用の森(jQuery/JavaScript 編) > Ajaxを使ったファイルダウンロードサンプル

package jp.dip.arimodoki.cntl;

import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import jp.dip.arimodoki.common.CConst;
import jp.dip.arimodoki.common.CheckBrowserIf;

@RestController
public class FileDownloadAjax implements CConst {

    @Autowired
    CheckBrowserIf		checkBrowser;	//ブラウザ判定クラス

    /**
     * Ajaxを使ったファイルダウンロード処理
     * 初期画面を表示します
     * filedownloadajax.html
     */
    @RequestMapping(value = "/filedownloadajax")
     public ModelAndView filedownloadajax() {
        return new ModelAndView("filedownloadajax");
    }

    /**
     * ファイルのアップロード処理を実施します
     * @param session HTTPセッション情報
     * @param uploadfile アップロードされたファイル情報
     * @return ブラウザに処理結果文字列を返します。
     * @throws Exception
     */
    @RequestMapping(value = "/upload_ajax",
            method = RequestMethod.POST,
            //Response結果の全角が文字化けするのを防ぐおまじない
            produces = "text/html;charset=UTF-8"
    )
    public String uploadajax(
       HttpSession session,
       @RequestParam("uploadfile") MultipartFile uploadfile
       ) throws Exception {

       //参考:@RequestParam("uploadfile") の"uploadfile" は、view側の
       //formData.append("uploadfile", file_data); で追加した時の左側の引数と同じ名前じゃないと
       //受け取れません。

      session.setAttribute("uploadfile", uploadfile);    //受信したファイル情報をセッションに保持しておく

        //Ajax呼び出し側に返却するJSON文字列を生成します。
        return "{\"status\":0,\"message\":\"Complete.\"}";
    }


    /**
     * upload_ajaxでアップロードされたファイルのダウンロードを実施します。
     * @param session HTTPセッション情報
     * @param req HTTPリクエスト情報
     * @param res HTTPレスポンス情報
     * @throws Exception
     */
    @RequestMapping(value = "/downloadajax")
     public void downloadajax(
             HttpSession session,
             HttpServletRequest req,
             HttpServletResponse res
         ) throws Exception {

        //upload_ajaxで保持したセッションからアップロードされたファイルの情報を取得します
        MultipartFile uploadfile = (MultipartFile)session.getAttribute("uploadfile");

        //ブラウザを判別します
        int blowser = checkBrowser.getBrowser(req.getHeader("user-agent"));
        //ファイル名に全角がある場合(Chrome/IE)Safari:NG
        String fname = URLEncoder.encode(uploadfile.getOriginalFilename(), "UTF-8");
        if(blowser == CheckBrowserIf.BROWSER_FF) {          //FireFox
            //ファイル名に全角がある場合FireFoxは以下で行ける
            res.setHeader("Content-Disposition","attachment; filename*=¥"UTF-8''"+fname+"¥"");
        } else {            //FireFox以外(ただし、Mac Safariは未確認)
            //attachment ⇒ inline にすれば、ブラウザで表示
            res.setHeader("Content-Disposition","attachment; filename=¥""+fname+"¥"");
        }
        //ファイルサイズ
        res.setContentLength((int) uploadfile.getSize());
        //レスポンスを返却
        FileCopyUtils.copy(uploadfile.getInputStream(), res.getOutputStream());

        //Session属性を削除
        session.removeAttribute("uploadfile");
        return;
    }
}