2

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.

Thomas Beauvais
  • 1,546
  • 2
  • 16
  • 30

2 Answers2

4

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.

Pavel Horal
  • 17,782
  • 3
  • 65
  • 89
  • This doesn't address that I want developers to be able to simple include a JSP and not have to know which controller to call in order to load the model. So, right now I have them calling directly the controllers and loading the model there. Though, I am concerned about performance overhead. – Thomas Beauvais May 26 '14 at 15:09
  • 1
    "*This* doesn't address" - which part of the answer you have on mind? Your idea using INCLUDE dispatch is fine... maybe you should check some component frameworks (e.g. JSF) if you want to initiate your MVC from the VIEW. Your kind of thinking is probably very similar to those of authors of these frameworks. – Pavel Horal May 26 '14 at 16:04
2

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

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.

Alan Hay
  • 22,665
  • 4
  • 56
  • 110
  • Thank you for the suggestions though none of them really address the problem. I want developers to be able to choose a template and wire up the jsp without care for path -> controller/model. It sounds like I will have to create something that will map a JSP directly to a set of methods that populate the necessary model. The controllers will merely handle redirect logic and such. – Thomas Beauvais May 26 '14 at 15:08