Search code examples
javaajaxspringform-data

How to add list of objects when sending formData to a spring server with ajax


The objs value is null in the code written as below. I tried various things, but as a result objs is null. How to add list of objects in FormData??

When checking the payload on the Network tab, objs is as follows.

obj[0]: {"name":"n1", "age":10}
obj[1]: {"name":"n2", "age":20}

Also, the value of objs is as follows when i check from HttpServletRequest request and request.getParameterMap().

["{"name":"n1", "age":10}", "{"name":"n2", "age":20}"]

javascript

$('#submit-button').click(
      function () {
        var objs = [{"name":"n1", "age":10}, {"name":"n2", "age":20}];
      
        var formData = new FormData();
        formData.append("title", $('#title').val());
        formData.append("summary", $('#summary').val());
        formData.append("content", $('#content').val());
        for (var i=0; i < objs.length; i++) {
          formData.append("objs[" + i + "]", JSON.stringify(objs[i])); //this is not working
          //formData.append("objs", objs[i]); //this is not working
          //formData.append("objs[" + i + "].name", objs[i].name); //this is not working
        }

        $.ajax({
          url: "/example",
          type: "POST",
          data: formData,
          enctype: "multipart/form-data",
          contentType: false,
          processData: false
        });
      }
    )

DTO in java spring

public record ExampleRequest(
        @NotBlank
        String title,
        @NotBlank
        String summary,
        @NotBlank
        String content,
        @NotNull
        List<OBJ> objs,
){}
public record OBJ(
    String name,
    Integer age
) {}

Controller

    @PostMapping("/example")
    public String example(
            @Validated @ModelAttribute ExampleRequest exampleRequest, //request.objs is null...
            BindingResult bindingResult
    ) {}

I want var objs = [{"name":"n1", "age":10}, {"name":"n2", "age":20}]; in javascript to be List<OBJ> in spring. Help me...


Solution

  • Your request on your Spring backend is expecting a List of "OBJ". Instead, you are giving multiple "OBJ" objects separately which would construct this:

    • key: "objs[0]", value: "{"name":"n1", "age":10}
    • key: "objs[1]", value: "{"name":"n2", "age":20}

    Instead, you should be doing:

    formData.append("objs", JSON.stringify(objs));
    

    Which will give you what you want:

    • key: "objs", value: "[{"name":"n1", "age":10}, {"name":"n2", "age":20}];"

    Spring will then know that this is a List of "OBJ" when it is mapping the data in the params to the expected object.

    Additionally, you are using multipart/form-data for enctype, which is intended for file-based requests (like a file upload). This should be "application/json" instead.