Skip to content
springside edited this page Feb 29, 2012 · 15 revisions

1.事务失效的惨案

Spring MVC最打击新人的事情,你必须保证spring-mvc.xml的context:component-scan只扫描Controller,而 applicationContext.xml里的不包含Controller. 否则你定义在applicationContext.xml里的事务就要失效了。方法如下:

spring-mvc.xml:

	<context:component-scan base-package="com.mycompany.myproject" use-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>

applicationContext.xml:

	<context:component-scan base-package="org.springside.examples.miniweb">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>

2.Struts2式的Preparable接口

Struts2有一个很实用的Preparable二次绑定功能: 表单提交时,先绑定一个ID,使用这个ID从数据库里找出对象来,再把表单的其他属性绑定到这个对象上,对于那些表单中的输入框数量比业务对象的实际属性少的情况很实用。

其实Spring MVC也有相同的能力,见mini-web中的GroupDetailController.

先用@ModelAttribute标注如下函数。SpringMVC会在执行任何实际处理函数之前,执行该函数并将返回值存为属性"group"

	@ModelAttribute("group")
	public Group getGroup(@PathVariable("id") Long id) {
		return accountManager.getGroup(id);
	}

再在save函数里,以@ModelAttribute标注表单处理函数的参数。SpringMVC就会按名称取出前面的对象,进行真正的Binding

	@RequestMapping(value = "save/{id}")
	public String save(@ModelAttribute("group") Group group, RedirectAttributes redirectAttributes) {
		accountManager.saveGroup(group);
	}

有个小可惜的地方是因为这个getGroup()会在任意函数都执行,但是有些函数(如create/list)不需要或者没有id在路径中,所有只好把这个Edit&Save的动作独立到另一个Controller了。

3.Struts2式的FlashAttribute

为了防止用户刷新重复提交,save操作之后一般会redirect到另一个页面,同时带点操作成功的提示信息。因为是Redirect,Request里的attribute不会传递过去,如果放在session中,则需要在显示后及时清理,不然下面每一页都带着这个信息也不对。Spring在3.1才提供了这个能力。

	public String save(@ModelAttribute("group") Group group, RedirectAttributes redirectAttributes) {
		accountManager.saveGroup(group);
		redirectAttributes.addFlashAttribute("message", "修改权限组成功");
		return "redirect:/account/group/";
	}

4.PropertyEditor 与 CheckBox绑定

在采用ORM的应用中,如果绑定子对象到页面上,以及在表单提交时如何把checkbox的内容重新绑回父对象是一个头痛的问题。

在mini-web示例中,User-Group组合的Group是一个复杂对象,而Group-Permission组合的Permission是一个简单的枚举。

对于简单的枚举,什么都不用做,直接用checkboxes的taglib就可以了。

	<form:checkboxes path="permissionList" items="${allPermissions}" itemLabel="displayName" itemValue="value" />

而Group这种对象就没这么好彩了,需要写一个针对gorupList的Editor,详见mini-web示例。不过虽然麻烦点,但最终效果还挺不错的。

5.输出跨域Ajax所需的JsonP

网上说什么扩展JsonView什么的太复杂了,自己拿Jackson生成一个JsonP的字符串返回就好了。

Clone this wiki locally