DispatcherServlet是否为每个用户创建了新的控制器和方法实例?

时间:2013-08-07 16:41:38

标签: java spring jsp java-ee spring-mvc

美好的一天。我的应用程序中有Controller:

        @Controller
        public class LoginSearchController {

            //List to store data from resultHTML method
            List<Cars> listCars = null;


            @Autowired
            private EducationWebServiceInterface educationWebService;

                //This method render jsp page for user and create model for resultHTML
                @RequestMapping(value="/search", method=RequestMethod.GET)
                public String search(FormBackingObjectSearch fbos, Model model) {   
                        model.addAttribute("fbosAttributes", fbos);

                    return "search";        
                }   

               //   This method get name form form back object and use it for fetchCarsByNameService method
              // After if something found it stores it in listofSerchObjects and after listofSerchObjects stores it in listForm List
                @RequestMapping(value="/result", method=RequestMethod.GET)
                public String resultHTML(@RequestParam String name,
                                         @ModelAttribute("fbosAttributes") FormBackingObjectSearch fbos, 
                                         BindingResult bindingResut, Model model) throws Exception {


                    listCars = new ArrayList<Cars>();
                    List<Cars> listofSerchObjects = null;

                    listofSerchObjects = educationWebService.fetchCarsByNameService(dateConvertation(fbos.getName()));
                        model.addAttribute("findAttributes", listofSerchObjects);   
                        listCars.addAll(listofSerchObjects);

                    return "search";
                }


                  //This method fetch data from listForm to make Excel document form the list
                @RequestMapping(value="/result.xls", method=RequestMethod.GET)
                public String resultXLS(Model model) throws Exception {

                        if(listCars == null || listCars.size() == 0) {
                            throw new NullPointerException("ArrayList<FormDate> formDateList is empty list");
                        } else {            
                            model.addAttribute("findAttributesXls", listForm);
                        }               
                    return "xlspage";
                }
        }

控制器中会发生什么:

用户依靠Search他希望找到的汽车页面填写名称(在我的情况下)和点击按钮FIND

- &GT;请求转到/result。此resultHTML方法从服务层调用fetchCarsByNameService以将对应于特定名称的数据提取到listofSerchObjects并在jsp页面上呈现它。在listofSerchObjects来自fetchCarsByNameService的数据后,它会将所有数据添加到其他列表listCars

- &GT;下一步,当所有数据都在jsp页面上呈现时,会出现按钮SAVE AS EXCEL,会发生什么:当用户单击此按钮时(如果用户也需要),它会转到/result.xls 并取出所有DATA FROM listCars将其保存在Excel文件中。

我很好奇,如果多个用户在我的网络应用程序中使用不同的计算机在同一个jsp页面上工作,我的listCars将如何表现。我很害怕它会存储最后一个数据女巫是从DataBase中提取的,如果user1想要在Excel文件中呈现它,如果user2最后搜索,他将拥有来自user2的数据。你认为呢???请给我建议。谢谢

4 个答案:

答案 0 :(得分:2)

您的listCars实例将在每个用户之间共享,因为您将其设置为类级变量。由于每个用户(和请求)都将获得自己的Thread,因此该类级别变量将在所有用户之间共享,并且您的数据可能会被破坏,具体取决于请求的进入速度。

答案 1 :(得分:2)

listCars已损坏,甚至可能偶尔抛出ConcurrentModificationException

以下是该问题的解决方法。

  1. listCars设为局部变量。

  2. 使用Controller

  3. @Scope("session")添加注释

    以下是一篇优秀的blog,其中介绍了Scope Controller及其优缺点。

答案 2 :(得分:1)

@Controller是一个Spring bean,它只会被容器实例化一次。保留与堆栈上特定请求相关的任何变量(在方法内声明)。

答案 3 :(得分:0)

listCars将在应用程序的所有用户之间共享。

/ result和/result.xls的两次调用完全相互独立。您需要再次查找汽车列表或将listCars作为参数传递给此方法。您还可以将listCars存储到用户的会话中并在result.xls调用期间检索它,但这会使用可能永远不会使用的不需要的数据污染会话。

取决于listCars可能的大小以及fetchCarsByNameService的成本应该确定您是将参数作为参数传回还是仅传入与/ result相同的参数并重新运行该方法。如果操作很昂贵,我可能会倾向于重新运行该方法并在fetchCarsByNameService上设置某种缓存。