Posts Tagged CustomCollectionEditor

CustomEditor for binding in Spring-MVC

In Spring MVC If you want to create a page with multi-select box , here are some tricks.
suppose that you have a command object defined like this :

public class FooCommand {
private Set<Foo> foos
//setter-getter
}
//Foo class
public class Foo {
private String id;
private String name;
//setter-getter
}

and you want to display a set of foo objects in a multi-select box.
your jsp page should look like this :

<form:form commandName="fooCommand">
<div><label for="tags"><spring:message code="layoutelementcontent.tags" /> </label>
<form:select path="foos" multiple="true">
<form:option value="">Select Here ---></form:option>
<c:forEach varStatus="loop" items="${fooList}" var="foo">
<form:option value="${foo.id}" label="${foo.name}"></form:option>
</c:forEach>
</form:select>
</div>
<input type="submit" value="submit" alt="Submit"/>
</form:form>

Most probably you won’t have any problem displaying the page. However things get nasty when you try to submit the page. Here is the binding error returned
Failed to convert property value of type [java.lang.String[]] to required type [java.util.Set]
In order to solve this problem you have to use CustomCollectionEditor and you need to register this editor just before binding operation starts.
So in your controller you should have some code like this :

@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
//do whatever
/* "foos" is the name of the property that we want to register a custom editor to
* you can set property name null and it means you want to register this editor for occurrences of Set class in * command object
*/
binder.registerCustomEditor(Set.class, "foos", new CustomCollectionEditor(Set.class) {
@Override
protected Object convertElement(Object element) {
String fooId = (String) element;
Foo foo = new Foo();
foo.setId(fooId);
return foo;
}
});
}

So basically what we have done above is we force binder to use our custom editor when the property “foos” is binded from request to our FooCommand object.

Comments (5)