2010-04-12 77 views
4

我在找到使用Spring MVC的意见 - 我将如何构建一个页面可以由几种不同的观点的事实 考虑一个控制器,它基本上是:春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(); ,下一次我想出新的东西时再改变一切。

这似乎很混乱。我如何构造这个?

`

回答

3

看看Tiles

+1

+1瓷砖与我的解决方案效果很好! – 2010-04-13 01:20:18

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

如果系统中每一页都需要显示的一种面板,那么你可以提供使用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窗格。但是,如果你的项目足够小,可能不值得费心。

0

我非常anticapte使用的HandlerInterceptor为您提供查看通用信息的建议。并延长从BART的答案和关于更容易建立拦截春天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>