spring mvc的表单类型转换太强大了,目前用到了两个简单的,
一个是将表单中的file自动映射成byte[],这样文件上传(如果使用blob)就无需写任何代码了。
另一个是将表单中的yyyy-MM-dd格式映射成java.util.Date,
假设User.java中有如下这两种特殊的属性:
public class User implements Serializable{
private Date birth;
private byte[] icon;
}
注册这两种属性编辑器只需在Controller中定义如下这样一个initBinder方法:
@Controller("userController")
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping(value = "create", method = RequestMethod.POST)
public String create(@ModelAttribute("user") User user,
RedirectAttributes redirectAttributes) {
userService.createUser(user);
redirectAttributes.addFlashAttribute("message", "create success!");
return SUCCESS;
}
@InitBinder
protected void initBinder(
WebDataBinder binder) throws ServletException {
binder.registerCustomEditor(byte[].class,
new ByteArrayMultipartFileEditor());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
}
ByteArrayMultipartFileEditor和CustomDateEditor都是spring直接提供的。可以参考这两个类的源码,
高级的自定义的还没用过,等用到的时候再补充到这里(2012-11-04补充)
今天终于用到了自定义的Editor,我现在有一个User对象,它有一个Set<Role> roles集合。
public class User implements Serializable{
public Set<Role> roles = new HashSet<Role>(); Role有id和name属性,
public class Role implements Serializable {
private Long id;//
private String name;//
UserController如下
@RequestMapping(value = "create", method = RequestMethod.GET)
public String createForm(ModelMap model) {
model.addAttribute("roleList", roleService.findAllRoles());
User user = new User();
model.addAttribute(user);
return "user/user_new";
} 我的user_new.jsp如下:
<div class="control-group">
<label class="control-label" for="roles">角色:</label>
<div class="controls">
<sf:checkboxes path="roles" items="${roleList }" itemValue="id" itemLabel="name"/>
</div>
</div> 用户在页面上check一个或多个角色,提交form,这时我们期望user对象中的roles集合能自动绑定用户选择的值,但是提交到服务器上的数据其实是一组roleId,我们需要在自定义的PropertyEditor中将其转成Role对象.
可以像这样定义RoleEditor.java
public class RoleEditor extends PropertyEditorSupport {
private RoleService roleService;
public RoleEditor(RoleService roleService) {
this.roleService = roleService;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text != null) {
Role role = roleService.findRoleById(Long.valueOf(text));
setValue(role);
} else {
setValue(null);
}
}
} 并在UserController中的initBinder方法中注册该编辑器
@InitBinder
protected void initBinder(
WebDataBinder binder) throws ServletException {
//@see http://forum.springsource.org/showthread.php?59612-Service-injection-amp-PropertyEditor
binder.registerCustomEditor(Role.class, new RoleEditor(roleService));
} 这时在UserController的create方法中取得的User对象就是已经绑定了roles的了
@RequestMapping(value = "create", method = RequestMethod.POST)
public String create(@ModelAttribute("user") User user,
RedirectAttributes redirectAttributes) {
userService.createUser(user);
redirectAttributes.addFlashAttribute("message", "create success!");
return SUCCESS;
}
值得注意的是,你必须要覆写Role的equals和hashCode方法,不然当你进入修改页面时,user的role属性不会自动的check上。
这里有人提相同的问题:
http://stackoverflow.com/questions/7421346/spring-binding-listobject-to-formcheckboxes
还有这里
http://stackoverflow.com/questions/8700339/spring-mvc-usage-of-formcheckbox-to-bind-data
参考:
http://www.mkyong.com/spring-mvc/spring-mvc-failed-to-convert-property-value-in-file-upload-form/
http://linkedjava.blogspot.com/2011/06/spring-controller-with-date-object.html(需要FQ)
http://forum.springsource.org/showthread.php?59612-Service-injection-amp-PropertyEditor
来源:oschina
链接:https://my.oschina.net/u/113421/blog/85727