Post Nested Object to Spring MVC controller using JSON

后端 未结 4 1402
一生所求
一生所求 2020-11-30 02:08

I have a controller with the POST handler defined like so:

@RequestMapping(value=\"/ajax/saveVendor.do\", method = RequestMethod.POST)
public @ResponseBody A         


        
4条回答
  •  长情又很酷
    2020-11-30 02:24

    first, sorry for my poor english

    in spring, if the param name is like object[0][field], they will consider it as a class type like sub

    public class Test {
    
        private List field;
    
        /**
         * @return the field
         */
        public List getField() {
            return field;
        }
    
        /**
         * @param field the field to set
         */
        public void setField(List field) {
            this.field = field;
        }
    }
    

    that's why the spring will throw an exception said something "is neither an array nor a List nor a Map".

    only when the param name is object[0].field, spring will treat it as a class's field.

    you could find the constants def in org.springframework.beans.PropertyAccessor

    so my solution is write a new param plugin for jquery, like below:

    (function($) {
      // copy from jquery.js
      var r20 = /%20/g,
      rbracket = /\[\]$/;
    
      $.extend({
        customParam: function( a ) {
          var s = [],
            add = function( key, value ) {
              // If value is a function, invoke it and return its value
              value = jQuery.isFunction( value ) ? value() : value;
              s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
            };
    
          // If an array was passed in, assume that it is an array of form elements.
          if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
            // Serialize the form elements
            jQuery.each( a, function() {
              add( this.name, this.value );
            });
    
          } else {
            for ( var prefix in a ) {
              buildParams( prefix, a[ prefix ], add );
            }
          }
    
          // Return the resulting serialization
          return s.join( "&" ).replace( r20, "+" );
        }
      });
    
    /* private method*/
    function buildParams( prefix, obj, add ) {
      if ( jQuery.isArray( obj ) ) {
        // Serialize array item.
        jQuery.each( obj, function( i, v ) {
          if (rbracket.test( prefix ) ) {
            // Treat each array item as a scalar.
            add( prefix, v );
    
          } else {
            buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, add );
          }
        });
    
      } else if (obj != null && typeof obj === "object" ) {
        // Serialize object item.
        for ( var name in obj ) {
          buildParams( prefix + "." + name, obj[ name ], add );
        }
    
      } else {
        // Serialize scalar item.
        add( prefix, obj );
      }
    };
    })(jQuery);
    

    actual I just change the code from

    buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
    

    to

    buildParams( prefix + "." + name, obj[ name ], add );
    

    and use $.customParam instead of $.param when do ajax request.

提交回复
热议问题