Spring MVC: Can not deserialize instance of out of START_ARRAY token

谁说胖子不能爱 提交于 2021-01-27 17:42:19

问题


I have been beating my head against this for a while now and still no joy. I am new to Spring and could really use some help.

I am trying to use Spring Boot to return a list of codes from a DB table. When I call my REST controller from a URL in a browser...

Example URL: localhost:8081/cis/utl/lookupchoice/O.s/

It returns this:

[
{"lookupId":10,"choiceGroup":"O.s","choiceCode":null,"displayLabel":"Pending","hidden":false,"displayOrder":1},
{"lookupId":11,"choiceGroup":"O.s","choiceCode":null,"displayLabel":"Active","hidden":false,"displayOrder":2},
{"lookupId":12,"choiceGroup":"O.s","choiceCode":null,"displayLabel":"Archived","hidden":false,"displayOrder":3},
{"lookupId":13,"choiceGroup":"O.s","choiceCode":null,"displayLabel":"Placeholder","hidden":false,"displayOrder":4}
]

But, I get an error message when trying to run this from a client controller. The call looks like this:

//
//Compiles but does not work
LookupChoice lookupChoice = restTemplate.getForObject(REST_URI+"/utl/lookupchoice/O.s/",
         LookupChoice.class);

The error: nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.MyPakage.repository.LookupChoice out of START_ARRAY token

Assuming the error occurs because an array is returned instead of a single object, I changed the code to this:

//
//Does not compile
Iterable<LookupChoice> lookupChoice = restTemplate.getForObject(REST_URI+"/utl/lookupchoice/U.r/",
         Iterable<LookupChoice.class>);

But, now I get an error in Intellij. It's indicating that an "Expression expected" for the Iterable<LookupChoice.class> param, and I can't get past this.

Thank you for your time and assistance, Ed

Thanks for your reply. I opted for this and it all seems to work now. Thanks for your help!

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Object[]> responseEntity;
Object[] lookupChoice;

responseEntity = restTemplate.getForEntity(REST_SERVICE_URI+"/utl/lookupchoice/O.s/" , Object[].class);
lookupChoice = responseEntity.getBody();
model.addAttribute("Status", lookupChoice);

回答1:


The reason it doesn't compile is because it's impossible in Java to pass a class of generic type parameters because they don't exist at runtime.

You have two options here, either use an array (LookupChoice[]) and convert it to a List<LookupChoice> if necessary:

restTemplate.getForObject(url, LookupChoice[]);

Or you can use the ParameterizedTypeReference:

restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<List<LookupChoice>>() {}).getBody()

It is an interface though, so either subclass it or use an anonymous class like I did in the code example above.

Also, ParameterizedTypeReference only works on the exchange() method if I'm not mistaken, so you'll get a ResponseEntity in stead of your raw object, so you'll have to use the getBody() method.



来源:https://stackoverflow.com/questions/38444651/spring-mvc-can-not-deserialize-instance-of-out-of-start-array-token

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!