有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring MVC从控制器中获取多个部件/视图

我正在研究如何使用SpringMVC——如何构造一个页面可以由多个不同视图组成的事实 考虑一个基本上是:

的控制器。
 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();,并且在下次我提出新的东西时再次更改所有内容

这看起来很乱。我如何构建这个

`


共 (4) 个答案

  1. # 1 楼答案

    看看Tiles

  2. # 2 楼答案

    我非常反对使用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>
    
  3. # 3 楼答案

    首先,可以扩展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()

  4. # 4 楼答案

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