虽然我已将其标记为 java/spring 问题,但可以轻松地向任何具有无状态 Controller 的 mvc 框架询问该问题。例如,我知道 Rails 使用简单的无状态 Controller ,所以也许你们知道如何最好地解决这个问题。我可以最好地描述 java/spring mvc 的问题,它是实现 - 请原谅 java 术语。
问题
我们很难找到一种令人满意的方法来在 spring mvc 中执行无状态到有状态的切换。 本质上给出的结构如下:
型号:单位
状态:已撤回、可用、不可用
以及操作:getOutline()
和 getHelp()
Controller :UnitController
操作:displayOutline()
和 displayHelp()
在执行操作displayOutline()
之前,我们需要一种方法来检查单元的状态(因为单元本身可能被撤回,因此用户应该被转发到撤回的页面)。
我们尝试了多种方法来做到这一点,包括:
极其简单的方法(任何语言)
Controller 中需要“可用”状态单元的所有方法都会在其实现的第一行调用 isAvailable() 方法。显然这里有很多复制,很臭。
AOP 方式(Java 特定)
可以创建一个名为 UnitAccess 的 @Around 建议,它会进行检查并重新路由控制流(即,不调用将调用底层方法的proceed(),而是调用 Controller 上的另一个方法)。这看起来像是一个 hack,并不是真正的 AOP,它确实消除了复制,但增加了复杂性并降低了透明度。
拦截器(由 servlet 架构提供,但可能在其他框架中可行)
这会检查单元状态并从本质上更改实际的 URL 调用。这又似乎不对。我们不喜欢在到达 Controller 之前调用模型逻辑的想法。
我们考虑过
命令模式
创建一个命令模式结构(使用继承)可以返回撤回 View 或有效的 displayOutline View 。因为执行方法将在 super() 调用中执行检查以及具体命令内的特定逻辑。即创建一个像这样的对象结构
DisplayOutlineCommand extends UnitCommand
public void execute(){
super();
// must be ok, perform getOutline()
}
最后,使用自定义异常
在服务级别对象上调用getAvailableUnit()
,该对象将在返回单元之前检查可用性等。如果单元被撤回,那么它将抛出 UnitWithdrawnException,该异常可以被 servlet 捕获并通过返回适当的 View 进行处理。我们仍然不相信。我们也不热衷于使用异常进行正常流量控制的想法。
我们错过了什么吗?在 spring/另一个无状态 Controller 框架下有一个简单的方法来做到这一点吗?
最佳答案
也许我没有捕获重点,但如果单位被撤回,用户为什么要来 Controller 呢?
我认为,如果该单元不“正常”,最好确保通常页面不会链接到要求该单元“正常”的 Controller 。 如果单元的状态在引用页面呈现和实际调用进入 Controller 之间发生变化(它不再是“OK”),那么使用异常来处理该事件对我来说似乎完全没问题(就像发生乐观锁定错误时发生异常一样)。
关于Java Spring MVC 无状态到有状态的切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1409185/