SpringMVC绑定到实体数组、list、set、和map时要注意

实体的属性前必定要用.分割,若是是使用jquery的ajax提交的一个js数组对象,则请求数据会被格式化为java

var sub = [{name:1,num:2},{name:1,num:2}]jquery

$.post(url,{test,sub})ajax

可是springmvc绑定实体时,是检测“.”符号,“.”以前的做为实体list在其bean中的名称,“.”以后的做为实体的属性而存在的,因此这里要用“.”来分割属性与list名spring

要想使用jquery自带的方法格式化为下面这种形式是不可能的(由于中间带有的.符号的特殊性),因而就只能这样提交了...本身构造一个这样的对象数组

var sub = {"test[0].num":1,"test[0].name":56,"test[1].num":2,"test[1].name":3}mvc

$.post(url,sub)app

这样是能够绑定的。post

 再说说后台的实体怎么写this

一、实体这样写:url

二、不能够在参数中直接写List<Test>,要在一个bean中把list做为成员,才可使用list绑定实体。

三、在请求参数中直接把TestBean做为参数便可

补充1:上面2:不能够在参数中直接写List<Test>,要在一个bean中把list做为成员,才可使用list绑定实体。

(由于直接绑定到参数名的特殊性,springmvc会直接实例化参数对象类型,接口就会实例化失败

nested exception is org.springframework.beans.BeanInstantiationException:

Could not instantiate bean class [java.util.List]: Specified class is an interface)

根本缘由是绑定到参数名与绑定到参数类型中的属性是不一样的逻辑,因此要把list做为成员才行。

若是是实体的话,能够经过反射获取到很是多的信息,可是参数就没那么简单了,因此这里要对这两种区别对待,简单类型直接绑定到参数名,复杂类型要写在实体中。

补充2:springmvc绑定实体时,是检测“.”符号。这个检查的代码在:

org.springframework.beans.AbstractPropertyAccessor的方法子类实现:org.springframework.beans.BeanWrapperImpl.setPropertyValue(String propertyName, Object value)中--

public void setPropertyValue(String propertyName, Object value) throws BeansException {
        BeanWrapperImpl nestedBw;
        try {
            nestedBw = getBeanWrapperForPropertyPath(propertyName);
        }
        catch (NotReadablePropertyException ex) {
            throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
                    "Nested property in path '" + propertyName + "' does not exist", ex);
        }
        PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
        nestedBw.setPropertyValue(tokens, new PropertyValue(propertyName, value));
    }

nestedBw = getBeanWrapperForPropertyPath(propertyName);这一句--

protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath) {
        int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
        // Handle nested properties recursively.
        if (pos > -1) {
            String nestedProperty = propertyPath.substring(0, pos);
            String nestedPath = propertyPath.substring(pos + 1);
            BeanWrapperImpl nestedBw = getNestedBeanWrapper(nestedProperty);
            return nestedBw.getBeanWrapperForPropertyPath(nestedPath);
        }
        else {
            return this;
        }
    }

的int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);获取第一个属性分隔符,属性分隔符就是“.”。其中代码是这样的

private static int getNestedPropertySeparatorIndex(String propertyPath, boolean last) {
        boolean inKey = false;
        int length = propertyPath.length();
        int i = (last ? length - 1 : 0);
        while (last ? i >= 0 : i < length) {
            switch (propertyPath.charAt(i)) {
                case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR:  //"["
                case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR:  //"]"
                    inKey = !inKey;
                    break;
                case PropertyAccessor.NESTED_PROPERTY_SEPARATOR_CHAR:  //"."
                    if (!inKey) {
                        return i;
                    }
            }
            if (last) {
                i--;
            }
            else {
                i++;
            }
        }
        return -1;
    }

默认的last为false,即从开始搜索。

 因此要使springmvc能够绑定最开始方括号那种属性到实体中,只须要对上面那一段作处理就好了,检测有两对[]的话,把最后一对换为.符号便可。具体有没有别的影响我不肯定。

相关文章
相关标签/搜索