Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failed to instantiate [java.util.List]: Specified class is an interface in GET request

In my spring boot REST API application, I need to handle HTTP GET by accepting a strongly-typed list as my input:

@RestController
public class CusttableController {

    @RequestMapping(value="/custtable", method=RequestMethod.GET)
    public List<MyObject> getCusttableRecords(List<Custtable> customers) {...}

This gives me this error:

org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface

What is the proper way for me to accept a strongly-typed List in Spring Boot, in a GET request?

like image 523
Anna Avatar asked Jan 01 '23 23:01

Anna


2 Answers

Add the annotation @RequestBody which says that the parameter is bound to the body of the HTTP request.

Another thing is that HTTP method GET method does not include a request body, so @RequestBody would be ignored. Change the method to POST.

@RequestMapping(value="/custtable", method=RequestMethod.POST)
public List<MyObject> getCusttableRecords(@RequestBody List<Custtable> customers) {
    // ...
}

Since Spring 4.3, you can use @PostMapping:

@PostMapping(value="/custtable")
public List<MyObject> getCusttableRecords(@RequestBody List<Custtable> customers) {
    // ...
}

Although according to the REST principles, the method POST should be used to create a new resource:

Request that the resource at the URI do something with the provided entity. Often POST is used to create a new entity, but it can also be used to update an entity.

However, this is the only workaround since your request is a bit unusual. I recommend you to change List to anything else and simpler to be passed through @RequestParam as part of URL. For example, you might need only IDs of those objects. Then you can use GET:

@RequestMapping(value="/cuttable", method=RequestMethod.GET)
public List<MyObject> getCusttableRecords(@RequestParam List<String> id) {
    // ...
}

URL would look like:

localhost:8080/cuttable?id=1&id=2&id=3
like image 183
Nikolas Charalambidis Avatar answered Jan 04 '23 16:01

Nikolas Charalambidis


You need to add @RequestBody to the customer parameter and use POST instead of GET.

@RestController
public class CusttableController {

    @RequestMapping(value="/custtable", method=RequestMethod.POST)
    public List<MyObject> getCusttableRecords(@RequestBody List<Custtable> customers) {...}

If you still want to use GET method then you could do the following:

@RestController
public class CusttableController {

    @RequestMapping(value="/custtable", method=RequestMethod.GET)
    public List<MyObject> getCusttableRecords(@RequestParam(name = "chooseAnAlias") List<Custtable> customers) {...}

and then make the call in the following manner:

domain.com/custtable?chooseAnAlias=value1&chooseAnAlias=value2&..chooseAnAlias=valueN

like image 41
dbl Avatar answered Jan 04 '23 17:01

dbl