我正在研究使用Spring MVC - 我如何构建一个页面可以由几个不同视图组成的事实 考虑一个基本上是控制器的控制器:
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
List<Post> posts = repository.getNewPosts();
return new ModelAndView("posts", "posts", posts);
}
但是,我决定在每个页面上,我还想要一个基于某些逻辑显示数据的“窗格”。那个“窗格”只是一个从上面的“帖子”视图中包含的.jsp,我可以将我的控制器更改为:
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
List<Post> posts = repository.getNewPosts();
List<Items> items= repository.getItems();
return new ModelAndView("model", "model", new MyCommonViewModel(posts,items));
}
但是我必须将每个控制器更改为List<Items> items= repository.getItems();
,并在下次出现新内容时再次更改所有内容。
这看起来很乱。我该如何构建这个?
`
答案 0 :(得分:3)
看看Tiles。
答案 1 :(得分:3)
如果系统中的每个页面都需要显示一种窗格,那么您可以使用interceptor为此提供模型数据。这几乎总是优于将代码放在抽象控制器中(如另一个答案所示),因为这会迫使您始终从该特定的类层次结构中扩展它。
public class YourInterceptor extends HandlerInterceptorAdapter {
private Repository repository;
public void setRepository (Repository repository) {
this.repository = repository;
}
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler)
throws Exception {
List<Post> posts = repository.getNewPosts();
List<Items> items= repository.getItems();
request.setAttribute("model", new MyCommonViewModel(posts,items));
}
}
将其连接起来
<beans>
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="yourInterceptor"/>
</list>
</property>
<property name="mappings">
<props>
<!-- SNIP -->
</props>
</property>
</bean>
<bean id="yourInterceptor"
class="your.YourInterceptor">
<property name="repository"><ref bean="repository" /></property>
</bean>
<beans>
您还可以使用sitemesh之类的内容。这允许您创建一个模板页面,该页面是所有其他页面(或某些页面集合的基础,具体取决于您的配置方式)。这将阻止您必须在每个页面上包含窗格jsp。但如果你的项目足够小,那可能就不值得了。
答案 2 :(得分:0)
首先,您可以扩展AbstractController,以便您拥有一个基类,可以加载您需要在所有控制器中使用的数据。
public class AbstractHasPaneController extends AbstractController {
public Object getPaneData() {
return repository.getItems();
}
// ...
}
然后,您的其他控制器扩展您的抽象控制器
public class MyPageController extends AbstractHasPaneController {
public ModelAndView
handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ModelAndView modelAndView = new ModelAndView("posts");
modelAndView.addObject( "posts", repository.getNewPosts() );
modelAndView.addObject( "model", this.getPaneData() );
return modelAndView ;
}
// ...
}
当你提出新的东西时,你需要编辑的就是AbstractHasPaneController.getPaneData()。
答案 3 :(得分:0)
我非常反对使用HandlerInterceptor为您的观点提供通用信息的建议。并且扩展了bart的答案并且更容易设置拦截器Spring 3.0提供了mvc配置命名空间
在顶级元素beans
上添加
xmlns:mvc="http://www.springframework.org/schema/mvc"
然后在bean配置中,您可以使用:
<mvc:annotation-driven />
<mvc:interceptors>
<bean class="org.example.web.interceptors.YourInterceptor"/>
</mvc:interceptors>