public class ListArgumentResolver implements HandlerMethodArgumentResolver{
final String DefaultPrefix = "list";
@Override
public boolean supportsParameter(MethodParameter mp) {
return mp.getParameterType() == List.class;
}
@Override
public Object resolveArgument(MethodParameter mp, ModelAndViewContainer mavc, NativeWebRequest req, WebDataBinderFactory bf) throws Exception {
log.debug("MethodParameter ... model:{}, method:{}", mavc.getModel(), mp.getMethod()); //.get("listWrapper")
Class c = (Class) ((ParameterizedType)mp.getGenericParameterType()).getActualTypeArguments()[0];
ListWrapper target = new ListWrapper(c);
//WebDataBinder binder = bf.createBinder(req, target, name);
ReqParamPrefix prefixAnno = mp.getParameterAnnotation(ReqParamPrefix.class);
String prefix = prefixAnno==null? DefaultPrefix : prefixAnno.value();
MutablePropertyValues pvs = new MutablePropertyValues();
Iterator<String> iter = req.getParameterNames();
while(iter.hasNext()){
String paramName = iter.next();
if(paramName.startsWith(prefix + '['))
pvs.addPropertyValue( prefix==DefaultPrefix? paramName : DefaultPrefix + paramName.substring(prefix.length()), req.getParameterValues(paramName));
}
// Map params = WebUtils.getParametersStartingWith(req.getNativeRequest(ServletRequest.class), prefix);
// MutablePropertyValues pvs = new ServletRequestParameterPropertyValues(req.getNativeRequest(ServletRequest.class), prefix, separator);
// ServletRequestDataBinder binder = new ExtendedServletRequestDataBinder(target);
// binder.bind(req.getNativeRequest(ServletRequest.class));
//binder.registerCustomEditor(
WebDataBinder binder = new WebDataBinder(target);
binder.bind(pvs);
if(mp.hasParameterAnnotation(Valid.class)){
binder.validate();
}
if (binder.getBindingResult().hasErrors()) {
throw new BindException(binder.getBindingResult());
}
List list = target.getList();
return list;
}
}
public class ListWrapper<T> implements java.io.Serializable{
private List<T> list;
public ListWrapper(Class<T> c){
this.list = new AutoPopulatingList(c);
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}