Java Spring MVC单例控制器-多个下载请求

Java Spring MVC单例控制器-多个下载请求,java,session,spring-mvc,singleton-methods,Java,Session,Spring Mvc,Singleton Methods,我知道SpringMVC控制器是单例的 因此,使用控制器的字段存储数据可能会导致安全问题 问题是,假设它有一个允许用户下载文件的映射- @RequestMapping(value = "downloadReport", method=RequestMethod.GET) public void downloadReport(@RequestParam("reportStoreId") String reportStoreId, HttpServletResponse re

我知道SpringMVC控制器是单例的

因此,使用控制器的字段存储数据可能会导致安全问题

问题是,假设它有一个允许用户下载文件的映射-

@RequestMapping(value = "downloadReport", method=RequestMethod.GET)
public void downloadReport(@RequestParam("reportStoreId") String reportStoreId,
            HttpServletResponse response, HttpServletRequest request) {
    // use reportStoreId to fetch a report from file system and pass it to user using PrintWriter, response.getWriter(), etc...
}

因此,如果多个用户同时请求下载具有不同ID的文件,是否会导致一个用户获得另一个用户请求的文件?

简短的回答是否定的

下面是不那么简短的答案。
对于每个请求,spring将调用控制器的方法,并将传递自己从HTTP请求解析的id值。堆栈变量与类字段非常不同。它的生命周期是不同的,它是在方法启动时创建的,在方法完成时销毁。另外,其他并发运行的线程也无法访问它,因此不会发生干扰

如果您的
downloadReport
的实现是成功的,那么您不必担心这一点

在您描述的情况下,多个线程将执行
downloadReport
。如果执行中使用的所有变量都在每个线程的堆栈上,则它们不会发生冲突。下面是一个简单的例子来说明:

@RequestMapping(value = "downloadReport", method=RequestMethod.GET)
public void downloadReport(@RequestParam("reportStoreId") String reportStoreId,
            HttpServletResponse response, HttpServletRequest request) {
    response.getWriter().print(getReportText(reportStoreId));
}

您需要实现
getReportText
以返回命名报告的文本或类似的内容。如您所见,
getReportText
根据其参数返回文本。此参数位于线程的调用堆栈上,并且对于每个请求都不同(当然,除非两个请求针对同一个文件)。

您认为这是为什么以及如何发生的?