我正在使用 Spring MVC 3.1.M1,JSP 2.1构建一个Web应用程序(没有Tiles,我使用纯JSP标签文件来构成我的布局).
基本上,我的页面是使用一些常见部分的布局构建的 – 页眉,页脚,横幅,菜单等.这些部分大部分是动态的,即包含当前用户的相关信息.
JSP没有“组件”概念,所以我无法将某个模板和其支持的java代码的一部分定义在一个地方,并联在一起.在我的@Controllers中,我必须完全填充我的模型,包括页眉,菜单和其他内容的数据.我真正想做的是避免这个代码重复.抽象的BaseController类与一些通用的模型种群方法也看起来不太好.
JSP和Spring MVC是一个经常被使用在一起的,所以我期望在这个问题上存在一些最佳实践.
让我们讨论一下
解决方法
1)方式第一,坏和不可用,只是在这里提到.抽象BaseController具有诸如populateHeaderData(Model Model),populateFooterData(Model model)等方法.扩展BaseController的所有控制器类中的所有@RequestMapping方法都调用这些方法来填充特定于布局的模型数据.
优点:无
2)@modelattribute方法,即隐式模型丰富.好像
@Controller @RequestMapping(value="/account") public class AccountController { @modelattribute("visitorName") private String putVisitor() { return visitorService.getVisitorName(); } // handler methods }
而在JSP中,
<span id="username">Welcome,${visitorName}!</span>
优点:不需要明确地称模型浓缩方法 – 它只是工作
缺点:这是一个棘手的事情. Spring MVC使用“推”模板模型而不是“拉”.在这种情况下,这意味着,当调用此类中定义的任何@RequestMapping方法时,将调用此类的所有@modelattribute方法.如果模板真的需要访客名称并且模板实际上存在特定操作,则没有区别.这包括POST请求表单提交等.事实上,这迫使我们改变控制器分离.例如,所有表单提交应该在单独的控制器类中,并且处理程序方法应以某种方式按布局分组.我必须更多地考虑它,也许它不是那么糟糕,因为它乍一看.
更多缺点:假设我们的布局A和B具有相同的非静态标题,而B和C具有相同的非静态页脚(所有其他部分都不同).我们不能为布局B实现基类,因为Java中没有多重继承.
向观众提问:
Spring MVC引用状态“处理程序方法支持以下返回类型:一个ModelAndView对象,该模型隐式丰富了命令对象和@modelattribute注释引用数据访问器方法的结果…”.这些命令对象是什么?
@Component("headerContext") public class HeaderContext { @Autowired private VisitorService visitorService; public String getVisitorName() { return visitorService.getVisitorName(); } // more getters here }
然后,通过这些bean将这些bean暴露给JSP EL
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/"/> <beans:property name="suffix" value=".jsp"/> <beans:property name="exposedContextBeanNames" value="headerContext,footerContext"/> </beans:bean>
<span id="username">Welcome,${headerContext.visitorName}!</span>
优点:“拉”策略(没有人问 – 没有任何东西被排除),容易使上下文@Scope(“请求”)并启用请求范围的缓存,没有多重继承的问题.只是在一个地方进行编码,在一个地方进行配置,并且可以在任何JSP或标签文件中用作通常的表达形式.
缺点:在一个框架内的push和pull的混合(必须更多地考虑它),在上下文实现类中没有Spring MVC支持(我的意思是控制器处理程序方法中的这些讨厌的预填充参数),只是spring bean.