Is including other JSP via the Spring MVC framewor

2019-02-15 14:19发布

问题:

This is a vague and grand question but hopefully I can explain it with as little concrete examples as possible.

We recently switched to Spring MVC for our application framework but found one (and really, only one) limiting factor during development: how to include dynamic views with the appropriate model.

For instance, we are creating a page that contains reusable fragments. On the left we have a "random q and a" fragment while on the top we have a common "navigation" fragment.

Each of these fragments requires a different model. I have been instructing the developer that is creating the "navigation" portion to create a navigation model, controller and view completely separate of the "q and a" model, controller and logic. This is to encourage reusability if another page layout wants the "navigation" but not the "q and a" or vice verse.

Do you see where I am going with this? The "home" page includes both fragments but it would be nice to not have to "known" which controller/model/view the fragments need.

I've been instructing developers to use Spring MVC in the following manner....

Example of home.jsp:

<body>
    <div class="top">
        <jsp:include page="/navigation"/>
    </div>
    <div class="left">
        <jsp:include page="/randomgQuestion"/>
    </div>
</html>

The idea is at request time the necessary other fragments will be pulled in dynamically with the models that they require.

Is this a good idea? Is there a better way?

Any discussion is welcome but please be constructive.

The goals are reusability and dumb views.

I'll offer any updates or clarifications upon request. Thank you.

回答1:

What you are describing feels a bit like portal / portlets functionality (JSR-286) => i.e. application (portal) generating webpages which are composed of content generated by other embedded applications (portlets). Portals are using INCLUDE dispatch (which is equivalent to <jsp:include>) to provide JSR-286 functionality. So from this point of view, it is a good idea to use <jsp:include> to provide reusable content blocks, each with its own MVC lifecycle (although sharing the same request attribute namespace)...

Also note that if you have just a simple fragment, which you would like to reuse in between JSPs, a simple <%@include file="menu.jspf" %> might be a better fit.

And I also feel that JSP tag functionality should be mentioned... making reusable content as a JSP TAG file (/WEB-INF/tags/[taglib-folder/]*.tag) can provide some advanced layout features. For even more advanced functionalities, you can implement Java based tag library.


To illustrate how I am using custom TAGs and include directive in one project, the following is a single JSP view:

<%@ include file="/WEB-INF/taglib.jspf" %>
<layout:admin section="test">
    <layout:admin-context />
    <layout:admin-content>
        <h1><spring:message code="test.overview.heading" /></h1>
        <h2><spring:message code="test.detail.heading" /></h2>
        <%@ include file="test-detail.jspf" %>
    </layout:admin-content>
</layout:admin>

We didn't have use-case, where INCLUDE dispatch (i.e. <jsp:include />) would be needed.



回答2:

Well in terms of your UI, Apache Tiles and Sitemesh are things you might want to look at here.

  • http://tiles.apache.org

  • http://wiki.sitemesh.org/wiki/display/sitemesh/Home

In terms of the controller layer, Spring has the @ControllerAdvice annotation which can be used to place model attributes in scope for all controllers. If, for example, you placed the navigation model in your @ControllerAdvice, no other controller would have to worry about setting it as a model attribute.

http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html

@ModelAttribute methods can also be defined in an @ControllerAdvice-annotated class and such methods apply to all controllers. The @ControllerAdvice annotation is a component annotation allowing implementation classes to be autodetected through classpath scanning.