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

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

package jp.dip.arimodoki.cntl;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

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

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import jp.dip.arimodoki.common.CConst;
import jp.dip.arimodoki.model.FormFileIf;

/**
 * ファイルアップロードサンプルクラス
 * 最大アップロードファイルサイズの例外処理
 * HandlerExceptionResolverをインプリメントする
 */
@Controller
public class FileUpload implements CConst, HandlerExceptionResolver {

    @Autowired      //リクエストパラメータFormBeanをDIする
    private FormFileIf frmupload;

    /**
     * FormFileクラスのデータモデルバインド処理
     * ここでは何もしない(ログを出したいだけ)が、そもそもこのメソッドは動かない
     * 常にresolveExceptionが実行されてしまう
     */
    @ModelAttribute("FormUpload")
    public FormFileIf setupBind() {
        logger.log_info(this,"setupBind");
        return this.frmupload;
    }

    /**
     * ファイルアップロード画面描画
     * このハンドラを実行すると、アップロード画面が開かず
     * resolveException()でいきなりエラー画面に飛んでしまう
     */
    @RequestMapping(value = "/fileupload")
     public String fileupload() {
        return "showupload";
    }

    /**
     * ファイルアップロード実施
     * 常にエラーページに飛ぶので、このハンドラメソッドが実行されない
     */
    @RequestMapping(value = "/upload")
     public String upload(
             @RequestParam MultipartFile uploadfile
         ) throws Exception {

            if(uploadfile.getOriginalFilename().length() >0) {
                    //アップロードファイルのサイズをロギング
                    logger.log_info(this, "uploadFile size:[" + uploadfile.getBytes().length+"]");
                    //保存ファイル名
                    File saveFile = new File("c:/temp/upload");
                    //ファイルの保存
                    FileUtils.copyInputStreamToFile(uploadfile.getInputStream(), saveFile);
            }

        return "fileuploaded";		//アップロード結果画面
    }

    /**
     * /fileupload.xhtmlを実行すると、正常/異常にかかわらず、
     * 常にこのメソッドが最優先で実行されてしまう。
     * 正常時のupload()ハンドラも実行されない
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest req,
            HttpServletResponse resp, Object obj, Exception e) throws MaxUploadSizeExceededException {
        Map<String, Object> model = new HashMap<>();
        if (e instanceof MaxUploadSizeExceededException) {
            //ここは通らず 下のerrorpage が表示されてしまう
            model.put("errorMsg", "Maximum upload file size");
        }
        return new ModelAndView("errorpage", model);
    }
}