我所有的控制器都扩展了以下抽象类:
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
、 theresponse
和model
as 方法参数。该解决方案工作正常,直到我发现这个问题:
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();
}
}
上述两种方法都使浏览器下载文件,但是download1
一种生成了一个空文件,而download2
生成了应有的原始文件。知道为什么吗?
感谢调试器,我注意到在postHandle
拦截器的方法中,该download2
方法生成了一个modelAndView
which equals null
,而该方法生成了download1
一个实例化的。这应该对这个问题意味着什么,但我找不到什么。
response
当作为控制器方法的参数传递时如何获得实例化?