0

私のコントローラーはすべて、次の抽象クラスを拡張します。

public abstract class AbstractController {

    public HttpServletRequest request;
    public HttpServletResponse response;
    public ModelMap model;

}

さらに、次のインターセプターを実装しました。

public class HttpRequestInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
        if (handler instanceof AbstractController) {
            AbstractController controller = (AbstractController) handler;
            controller.request = request;
            controller.response = response;
            controller.model = new ModelMap();
        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        if (handler instanceof AbstractController && modelAndView != null) {
            AbstractController controller = (AbstractController) handler;
            modelAndView.addAllObjects(controller.model);
        }
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

}

requestこれは、コードの因数分解を改善するために見つけた解決策です。コントローラー内で、 、responseおよびmodelas メソッド パラメーターを渡す必要がないためです。この問題が見つかるまで、ソリューションは正常に機能します。

public class HomeController extends AbstractController {

    @RequestMapping
    public void download1() {
        // use the parent attribute response
        File file = new File(MY_FILE_PATH);
        InputStream in = new BufferedInputStream(new FileInputStream(file));
        ServletOutputStream out = response.getOutputStream();
        IOUtils.copy(in, out);
        response.flushBuffer();
    }

    @RequestMapping
    public void download2(HttpServletResponse response) {
        // use the response passed as parameter
        File file = new File(MY_FILE_PATH);
        InputStream in = new BufferedInputStream(new FileInputStream(file));
        ServletOutputStream out = response.getOutputStream();
        IOUtils.copy(in, out);
        response.flushBuffer();
    }

}

上記の 2 つの方法はどちらもブラウザにファイルをダウンロードさせますが、download1一方は空のファイルをdownload2生成し、一方は本来のファイルを生成します。理由はありますか?

デバッガーのおかげpostHandleで、インターセプターのメソッドで、メソッドが等しいをdownload2生成するのに対し、メソッドはインスタンス化されたものを生成することに気付きました。これは問題にとって何かを意味するはずですが、何を見つけることができません。modelAndViewnulldownload1

responseコントローラーのメソッドのパラメーターとして渡されたときに、どのようにインスタンス化されますか?

4

2 に答える 2

7

これをしないでください:

public abstract class AbstractController {

    public HttpServletRequest request;
    public HttpServletResponse response;
    public ModelMap model;

}

コントローラーのインスタンス変数 (シングルトン btw のデフォルト スコープを持つ) は悪い考えです。

于 2012-09-17T13:02:45.443 に答える
3

このようなものを(txtファイルに)作成するだけです:

@RequestMapping(value="/download", method=RequestMethod.GET, produces=MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public String download(HttpServletResponse response) throws IOException {
    response.setContentType("application/force-download");
    FileReader fr = new FileReader("/folder/file.extension");
    return IOUtils.toString(fr); // IOUtils come from Apache Commons IO
}
于 2012-12-12T19:03:32.547 に答える