1:代码实例
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
binder.registerCustomEditor(SystemInfo.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
return;
}
{
Long systemInfoId = Long.valueOf(text);
SystemInfo systemInfo = systemInfoService.findById(systemInfoId);
setValue(systemInfo);
}
}
});
binder.registerCustomEditor(Category.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
return;
} else {
Long categoryId = Long.valueOf(text);
Category category = categoryService.findById(categoryId);
setValue(category);
}
}
});
}
- <form:form modelAttribute="categoryEditForm" id="categoryForm" method="post" action="saveOrUpdate.do">
- <form:hidden path="category.objectId" />
- <input type="hidden" name="category.parent" value="${categoryEditForm.category.parent.objectId}"/>
- <input type="hidden" name="category.systemInfo" value="${categoryEditForm.category.systemInfo.objectId }"/>
- <div class="area">
- <div class="areaTitle">
- <div class="inner">
- <label>Category Information Form</label>
- <div class="clear"></div>
- </div>
- </div>
- </div>
- <div class="areaBody">
- <table class="formTable">
- <tbody>
- <tr>
- <td colspan="4">
- <span class="button"><span><a href="javascript:sumbit();" class="btnSave">Submit</a></span></span>
- </td>
- </tr>
- <tr>
- <td colspan="4"> </td>
- </tr>
- <tr>
- <td align="right">Parent Category Name:</td>
- <td colspan="3"><form:input path="category.parent.name.fullName" readonly="true" id="parentCategory" cssClass="input readOnly" /></td>
- </tr>
- <tr>
- <td align="right">Current Category Name:</td>
- <td><form:input path="category.name.fullName" id="categoryName" cssClass="input"/></td>
- <td align="right">description:</td>
- <td><form:input path="category.description" id="description" cssClass="input"/></td>
- </tr>
- </tbody>
- </table>
- </div>
- </form:form>
2、实例2
spring mvc的表单类型转换(custom property editor)
spring mvc的表单类型转换太强大了,目前用到了两个简单的,
一个是将表单中的file自动映射成byte[],这样文件上传(如果使用blob)就无需写任何代码了。
另一个是将表单中的yyyy-MM-dd格式映射成java.util.Date,
假设User.java中有如下这两种特殊的属性:
1 | public class User implements Serializable{ |
2 | private Date birth; |
3 | private byte [] icon; |
4 | } |
注册这两种属性编辑器只需在Controller中定义如下这样一个initBinder
方法:
01 | @Controller ( "userController" ) |
02 | @RequestMapping (value = "/user" ) |
03 | public class UserController { |
04 | @RequestMapping (value = "create" , method = RequestMethod.POST) |
05 | public String create( @ModelAttribute ( "user" ) User user, |
06 | RedirectAttributes redirectAttributes) { |
07 | userService.createUser(user); |
08 | redirectAttributes.addFlashAttribute( "message" , "create success!" ); |
09 |
10 | return SUCCESS; |
11 | } |
12 | |
13 | @InitBinder |
14 | protected void initBinder( |
15 | WebDataBinder binder) throws ServletException { |
16 | binder.registerCustomEditor( byte []. class , |
17 | new ByteArrayMultipartFileEditor()); |
18 | |
19 | SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" ); |
20 | dateFormat.setLenient( false ); |
21 | binder.registerCustomEditor(Date. class , new CustomDateEditor(dateFormat, false )); |
22 | } |
23 | } |
ByteArrayMultipartFileEditor和CustomDateEditor都是spring直接提供的。可以参考这两个类的源码,
高级的自定义的还没用过,等用到的时候再补充到这里(2012-11-04补充)
今天终于用到了自定义的Editor,我现在有一个User对象,它有一个Set<Role> roles集合。
1 | public class User implements Serializable{ |
2 | public Set<Role> roles = new HashSet<Role>(); |
1 | public class Role implements Serializable { |
2 | private Long id; // |
3 | private String name; // |
UserController如下
1 | @RequestMapping (value = "create" , method = RequestMethod.GET) |
2 | public String createForm(ModelMap model) { |
3 | model.addAttribute( "roleList" , roleService.findAllRoles()); |
4 | User user = new User(); |
5 | model.addAttribute(user); |
6 | return "user/user_new" ; |
7 | } |
1 | < div class = "control-group" > |
2 | < label class = "control-label" for = "roles" >角色:</ label > |
3 | < div class = "controls" > |
4 | < sf:checkboxes path = "roles" items = "${roleList }" itemValue = "id" itemLabel = "name" /> |
5 | </ div > |
6 | </ div > |
可以像这样定义RoleEditor.java
01 | public class RoleEditor extends PropertyEditorSupport { |
02 | private RoleService roleService; |
03 |
04 | public RoleEditor(RoleService roleService) { |
05 | this .roleService = roleService; |
06 | } |
07 |
08 | @Override |
09 | public void setAsText(String text) throws IllegalArgumentException { |
10 | if (text != null ) { |
11 | Role role = roleService.findRoleById(Long.valueOf(text)); |
12 | setValue(role); |
13 | } else { |
14 | setValue( null ); |
15 | } |
16 | } |
17 | } |
1 | @InitBinder |
2 | protected void initBinder( |
3 | WebDataBinder binder) throws ServletException { |
4 | //@see http://forum.springsource.org/showthread.php?59612-Service-injection-amp-PropertyEditor |
5 | binder.registerCustomEditor(Role. class , new RoleEditor(roleService)); |
6 | } |
1 | @RequestMapping (value = "create" , method = RequestMethod.POST) |
2 | public String create( @ModelAttribute ( "user" ) User user, |
3 | RedirectAttributes redirectAttributes) { |
4 | userService.createUser(user); |
5 | redirectAttributes.addFlashAttribute( "message" , "create success!" ); |
6 |
7 | return SUCCESS; |
8 | } |
值得注意的是,你必须要覆写Role的equals和hashCode方法,不然当你进入修改页面时,user的role属性不会自动的check上。
RoleEditor可以简化成
public class RoleEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text != null) {
Role role = new Role();
role.setId(Long.valueOf(text));
setValue(role);
} else {
setValue(null);
}
}
}
保存时只用了id值,没有必要去数据库再查找一次