0

I'm sending to a Spring Controller an Ajax GET request with an Array Parameter,

        $.ajax({
            url: "getChoices",
            dataType: "json",
            type: "get",
            data: {
                'myarg': myarray // JS array of strings, ["a","b","c"]
                                 // Verified to be correct
            },

Controller Method that should receive this argument -- the arg name matches:

@ResponseBody
@GetMapping("/getChoices")
public List<KeyValueBean> getChoices(List<String> myarg) {
    //...
}

First of all, the way this is written above, I'm getting the error:

[java.lang.IllegalStateException: No primary or default constructor found for interface 
 java.util.List]

Caused by: java.lang.NoSuchMethodException: java.util.List.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getDeclaredConstructor(Class.java:2178)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:216)

Then I tried making some tweaks:

1) Made the method signature a String[], that's not what I want -- I need a List -- but tried it just in case:

public List<KeyValueBean> getChoices(String[] myarg) {

This came into the method, but myarg is NULL and didn't get set correctly.

2) Kept a List<String> but tried JSON.stringify around the array:

JSON.stringify(myarray)

Same exception: [java.lang.IllegalStateException: No primary or default constructor found for interface java.util.List]

How do I pass an Array arg in an Ajax GET request in Spring Boot?

gene b.
  • 10,512
  • 21
  • 115
  • 227

2 Answers2

1

You forgot to annotate your parameter with @RequestParam.

@GetMapping("/testList")
public void test(@RequestParam("myarg") List<String> myarg) {
    for (String str : myarg) {
        System.out.println(str);
    }
}

You can fire a request to your endpoint as following and it will work.

http://localhost:8080/testList?myarg=abc,def

enter image description here

Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • Thanks, but even without `@RequestParam`, all my regular (non-array) params work and come in correctly. I thought this annotation wasn't necessary anymore, because things always worked without. The only case where it doesn't work is with arrays. – gene b. May 09 '19 at 02:17
  • @geneb.: I gave you the final format of the link in my answer. Just make sure your JS code actually submit a request in that format. Your array might have been translated to something else. – Mr.J4mes May 09 '19 at 02:20
  • 1
    @geneb. edited my answer to give you a picture of the request from Postman as well :) – Mr.J4mes May 09 '19 at 02:21
  • 1
    @geneb. oh I got what you mean. I tried to remove `@RequestParam` from my test bean and I got the same error as well ;). `@RequestParam` is a must. – Mr.J4mes May 09 '19 at 02:23
  • 1
    thanks I'll confirm tomorrow. Appreciate the response. – gene b. May 09 '19 at 02:25
  • No, the solution given still gives `Required List parameter 'myarg' is not present`. I found the solution and replied: it's to include `[]` in the RequestParam value. Apparently JS tries to send `[]` with the name of the object. – gene b. May 09 '19 at 17:05
  • @geneb. the solution you found is for another problem of your JS code :). `@RequestParam` and the sample code I gave you is what you need to make it work with a GET request. I wrote the code myself in Eclipse to reproduce your error and fixed it. – Mr.J4mes May 09 '19 at 17:07
0

The only thing that worked for me is to specify [] in @RequestParam value:

@ResponseBody
@GetMapping("/getChoices")
public List<KeyValueBean> getChoices(@RequestParam(value="myarg[]")String[] myarg) {
    //...
}

This is atually explained here, https://stackoverflow.com/a/5702905/1005607

it is due to a parameter naming incompatibility between Spring and jQuery, where jQuery wants to put square brackets in to indicate that a parameter is an array (I think PHP likes this too), but where Spring doesn't care.

gene b.
  • 10,512
  • 21
  • 115
  • 227