zoukankan      html  css  js  c++  java
  • SpringMVC绑定到实体数组、list、set、和map时要注意

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

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

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

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

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

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

    $.post(url,sub)

    这样是可以绑定的。

     再说说后台的实体怎么写

    1、实体这样写:

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

    3、在请求参数中直接把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可以绑定最开始方括号那种属性到实体中,只需要对上面那一段做处理就行了,检测有两对[]的话,把最后一对换为.符号即可。具体有没有别的影响我不确定。

  • 相关阅读:
    【数据结构】Trie树
    【算法】动态规划经典题之最长公共子序列
    【Leetcode】583. Delete Operation for Two Strings
    【Java】SpringBoot入门学习及基本使用
    【Java学习】调用ByteBuffer.getInt()方法得到808464432
    Install rapyuta Robot Cloud Engine on Ubuntu14.04
    Install rapyuta Robot Cloud Engine on Ubuntu12.04
    怎样下载youtube的字幕
    国内老版本ubuntu更新源地址以及sources.list的配置方法
    配置 ROS 的 apt 源
  • 原文地址:https://www.cnblogs.com/guangshan/p/4940154.html
Copyright © 2011-2022 走看看