Spring MVC、Tiles、多个控制器
我正在为即将到来的项目尝试 Spring MVC。我需要应用程序中的一些网页来呈现多个可重用的“组件”,并认为 Tiles 应该帮助我实现这一点?每个组件都有自己的控制器。
我整理的示例仅部分有效。这是一个包含 3 个图块的页面。第三个图块有一个控制器,它尝试将 ArrayList(通过 @ModelAttribute 注释)返回给客户端,但当视图作为图块包含时,ArrayList 为空。
这是 *-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/"/>
<property name="suffix" value=".jsp"/>
</bean>
这是我的图块配置 (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>
这是相关图块背后的 JSP 代码。 “widgetsList”表达式是绑定到控制器方法的表达式,但当此视图作为图块包含时返回为空。
<%@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>
这是控制器:
@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;
}
}
当我直接访问视图“widgets.jsp”时,“widgetsList”属性会被填充,只有当它作为图块添加时才不会返回任何内容。
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/"/>
<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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Tiles 只为您提供一个复合视图,而使用 Spring MVC 控制器只能返回一个视图,在这种情况下,单个控制器将返回整个 Tiles 定义的页面。
我对tiles配置没有太多经验,但是只有当你可以将控制器映射的URL(而不是JSP)作为tiles元素时,你想要实现的目标才是可能的,这样tiles处理器将调用spring控制器每个“组件”。
但是既然您正在谈论组件并且您似乎在这里需要它们,为什么不从面向组件的框架开始(例如,Wicket 可以轻松地与 Spring 开箱即用地集成)。
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).
我发现这样做的一个很好的模式是使用 jQuery、ajax 和 json 以及tiles。在您希望小部件包含一个标记 div 的页面上,例如
使用 jQuery 在页面加载时检查此 div,如果存在,则对该内容的控制器进行 json 调用。
这种方法很棒,因为当您包含下面的 javascript 时,每个页面的控制器不需要了解除其自己的模型信息之外的任何模型信息。我用它来填充常见信息,例如动态的页眉和页脚。
http://api.jquery.com/jQuery.getJSON/
使用 Jackson 从 Spring 控制器获取 Json 教程
http://www.mkyong.com/spring- mvc/spring-3-mvc-and-json-example/
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
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.
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/