在使用多个控制器类和 DefaultAnnotationHandlerMapping 时,我们在使用 Spring Portlet MVC 3.1 时遇到了问题。
背景
- 我们使用 Spring Portlet MVC 3.1 和 Render & Action 阶段的注释
- 我们正在使用 JBoss EPP 5.1.1
问题
- 对于带有参数的 Portlet 呈现请求,Portlet 中呈现了不正确的页面
原因
- Spring Portlet MVC 使用的 @RenderMapping 方法与具有正确注释的预期方法不同
技术分析
我们所有的控制器都包含@RenderMapping 和@ActionMapping 注释,并且都具有“params”参数,以确保根据我们的portlet URL 中的参数集调用预期的方法。对于默认渲染,我们有一个方法,它有一个没有“params”参数的@RenderMapping 注解,当请求不包含参数时,我们使用它来渲染一个空白的JSP。
根据对本书第 7 章和第 8 章的阅读,我们了解到 Dispatcher Portlet 尝试为传入请求获取适当的处理程序映射,并将其发送到配置的控制器 bean 中的适当方法。我们的假设是,我们的默认 @RenderMapping 注释(没有参数)只有在它检查控制器中没有其他方法与特定请求参数匹配的注释后才会被调用。
然而,我们经过调试发现这个假设是不正确的。DefaultAnnotationHandlerMapping 似乎以某种预定义的顺序遍历 Controller bean 中可用的注释列表。这意味着,如果具有默认 @RenderMapping 注释(没有参数)的控制器 bean 出现在列表之前,则将调用具有默认 @RenderMapping 注释(没有参数)的方法,而不是列表下方的正确方法.
显示的错误
我们在 Windows 环境下开发并部署到 Linux 环境。在 Windows 中,我们看到处理程序按字母顺序循环通过控制器 bean,因此我们最初通过在控制器中添加不带参数的 @RenderMapping 注释方法来解决我们的问题,其中 bean 名称最接近“Z”。
然而,在 Linux 中,控制器 bean 的检测顺序似乎有所不同。我附上了下面的 Spring 日志以突出显示该问题。无参数 @RenderMapping 注释在 YourDetailsController 中,正如您在 Windows 日志中看到的那样,它出现在列表的最后,而在 Linux 中则没有。这意味着,如果我们尝试访问出现在列表中 YourDetailsController 之后的控制器之一,我们最终总是会点击 YourDetailsController 中的 no params 注释。
问题
- 我们的假设不正确吗?
- 我们的诊断是否反映了预期的行为?还是 Spring Portlet MVC 的错误?
- 是否有其他方法可以扫描注释以形成处理程序映射 bean 列表?
- 使用 xml 配置(而不是注释)会解决我们的问题吗?
- 我们能否定义多个处理程序映射和顺序,以便默认处理程序映射是调度程序 portlet 使用的最后一个处理程序映射?
您对此问题的任何想法或建议将不胜感激。