【发布时间】:2012-05-24 20:37:41
【问题描述】:
我对 Spring 比较陌生,所以有一点对我来说不是很明显。即,控制器是单例的事实。我同意这是一个很好的方法,但这并不能让我实现我以前用其他框架实现的东西。
我构建了一个使用 AJAX 请求的 Web 应用程序。我有以BaseController 作为父级的控制器层次结构,所有其他控制器都对其进行了扩展。
应该向客户端返回响应的控制器操作使用@ResponseBody 注释进行注释,并将序列化的 JSON 字符串返回给客户端。
执行此序列化的方法createJSONResponse()在BaseController中实现,这里的主要思想是每个子控制器的操作都使用客户端数据所需的映射Map<String, Object> responseMap,然后访问此映射在BaseController 中并序列化。
我不想在每个操作中都创建responseMap 的新实例,也不想每次都将它作为createJSONResponse() 的参数传递。
我通过将BaseController 中的responseMap 声明为protected 属性来实现这一点。
我不能用 Spring 做到这一点,因为所有控制器都是单例的,我不会在每个请求中都有 responseMap 的新实例。
我不确定将BaseController 请求范围设为一个好主意。
我创建了一个助手类作为请求范围的 bean,并在这个助手中声明了 responseMap。然后我将这个 bean 作为@Autowired 注入BaseController。我还在这个助手中移出了createJSONResponse() 方法。然后从控制器中我将此地图填充为helper.responseMap.add(<somedata>) 并调用helper.createResponseMap()。
在这种情况下,responseMap 在createResponseMap() 中变为空,它不包含在控制器操作中填充的数据。不知何故,responseMAp 不是线程安全的,它随着每个异步请求在线程之间移动。
有什么方法可以实现我需要的功能吗?
通过变通方法解决: 通过在每个请求之前实例化 responseMap 并添加到请求拦截器中的 HttpServletRequest 对象来解决问题。然后createJSONResponse() 方法和responseMap 填充方法参考getRequestMap() 方法从HttpServletRequest 中获取responseMap。
附:仍然会很高兴知道更好的解决方案。
【问题讨论】:
-
"我不想在每个动作中创建新的 responseMap 实例,也不想每次都将它作为 createJSONResponse() 的参数传递" --- 为什么不呢?这是最简洁、最容易阅读的设计。
-
是的。这很干净,但在我看来不是最好的解决方案。我更喜欢 DRY 方法,在控制器的操作中不重复同一行代码。
标签: spring servlets spring-mvc controller