开发者

Spring MVC, Tiles, Multiple Controllers

I'm experimenting with Spring MVC for an upcoming project. I'll need some web pages in the application to render multiple reusable "components" and figured that Tiles should help me accomplish this? Each component would have it's own controller.

The example I've put together is only partially working. It's a page with 3 tiles. The 3rd tile has a controller that's trying to return an ArrayList (via @ModelAttribute annotation) to the client but the ArrayList is empty when the view is included as a tile.

Here's the tiles setup in *-servlet.xml:

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
        <property name="order" value="0"/>
</bean>

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles-config/tiles.xml</value>
            </list>
        </property>
</bean>

<bean id="viewResolver2" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="order" value="1" />
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
开发者_如何学JAVA        <property name="suffix" value=".jsp"/>
</bean>

Here's my tiles config (tiles.xml):

<tiles-definitions>
    <definition name="parent" template="/WEB-INF/jsp/tiles/parent_layout.jsp">
        <put-attribute name="header" value="/WEB-INF/jsp/tiles/header.jsp"/>
        <put-attribute name="body" value=""/>
        <put-attribute name="recordsSection" value=""/>
        <put-attribute name="widgetsSection" value=""/>
    </definition>
        <definition name="_n/list.htm" extends="parent">
            <put-attribute name="recordsSection" value="/WEB-INF/jsp/_n/list.jsp"/>
            <put-attribute name="widgetsSection" value="/WEB-INF/jsp/_n/widgets.jsp"/>
        </definition>
</tiles-definitions>

Here's the JSP code behind the tile in question. The "widgetsList" expression is what is bound to the controller method but coming back empty when this view is included as a tile.

<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="display" uri="http://displaytag.sf.net" %>

<h3>Widgets</h3>
<p>widgetsList=${widgetsList}</p>
<div id="displaylist">
    <display:table id="items" name="${widgetsList}" cellspacing="0" export="true">
        <display:column title="Widget ID" property="widgetId"/>
        <display:column title="Widget Name" property="widgetName"/>
        <display:column title="Widget State" property="widgetState"/>
    </display:table>
</div>

Here's the controller:

@Controller
public class WidgetController {

    @Autowired
    private WidgetDaoImpl widgetDao = new WidgetDaoImpl();

    @RequestMapping("_n/widgets.htm")
    public String widgets() {
        return "_n/widgets.htm";
    }

    @ModelAttribute("widgetsList")
    public ArrayList<Widget> getWidgets() {
        System.out.println("executing getWidgets()");
        ArrayList<Widget> records = widgetDao.listWidgets();
        return records;
    }
}

When I access the the view "widgets.jsp" directly, the "widgetsList" attribute gets populated, it's only when it's added as a tile that it returns nothing.


Tiles only gives you a composite view and with Spring MVC a controller can only return one view, in this case a whole tiles-defined page will be returned by a single controller.

I don't have much experience with tiles configuration, but what you're trying to achieve is only possible if you can have controller-mapped URLs (and not JSPs) as tiles elements, so that the tiles processor will invoke the spring controllers for each of the "components".

But since you're talking about components and you seem to need them here, why not start with a component oriented framework (Wicket for instance can easily be integrated with Spring out-of-the box).


A pattern i found great while doing this is using jQuery, ajax and json with tiles. On the pages you want your widgets include a marker div like

<div id="displayWidgets"></> 

With jQuery check for this div on page load and if it exists do a json call to the controller for this content. This approach is great because when you include the javascript below, the controller for each page doesn't need to know about any model information except its own. I use this for populating common information like headers and footers that are dynamic.

$.ready(){
    if($('div#displayWidgets')){
         $.getJSON('/widgetsList', function(data) {
             //loop over json and create your html, url below has great examples
         }
    }
}

http://api.jquery.com/jQuery.getJSON/ Json tutorial from spring controller using jackson http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜