[英]restTemplate.getForEntity when reading data that contains a list with single element gives Exception
I have a Detail object that has a property of object of type Product. 我有一个Detail对象,该对象具有Product类型的对象的属性。 Product has a property called xxx which is an arraylist.
产品具有名为xxx的属性,该属性是一个数组列表。 I do a GET on the URL with postman and the result looks like:
我用邮递员在URL上执行GET,结果如下所示:
"Product": {
"id": "2",
"xxx": [
"price": "50"
},
{
"price": "60"
}
]
}
This result is good. 这个结果很好。 But, in my Spring project, when I do a get Using RestTemplate as:
但是,在我的Spring项目中,当我执行使用RestTemplate作为:
restTemplate.getForEntity("someurl", Detail.class).getBody();
I get correct results when xxx list contains 2 or more element. 当xxx列表包含2个或更多元素时,我得到正确的结果。 However, when there is only element in this list, I get an error:
但是,当此列表中只有元素时,出现错误:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
How do I fix this issue that I am facing with my call to restTemplate.getForEntity as above?
I suspect that your encounter this error not when your list contains one item but rather when you have no list at all but a plain object, thus the parser complains about a misplaced START_OBJECT
token. 我怀疑您不是在列表包含一个项目时遇到此错误,而是在您没有列表但只有一个普通对象的情况下遇到此错误,因此解析器抱怨
START_OBJECT
了一个错误的START_OBJECT
令牌。 To remedy this and without being able to edit Swagger-generated domain classes, you could set the deserialization feature 为了解决此问题,并且无法编辑Swagger生成的域类,可以设置反序列化功能
ObjectMapper objectMapper = new ObjectMapper(); // maybe injected
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
directly on the ObjectMapper
that you are using. 直接在您使用的
ObjectMapper
上。
This object mapper can now be put into the RestTemplate
config: 现在可以将该对象映射器放入
RestTemplate
配置中:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class JsonControllerIT {
@LocalServerPort
private int port;
@Test
public void jsonWithSerializationFeatureSet() {
// given
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
messageConverter.setObjectMapper(objectMapper);
restTemplate.getMessageConverters().removeIf(m -> m.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName()));
restTemplate.getMessageConverters().add(messageConverter);
// when
Detail detail = restTemplate.getForEntity("http://localhost:" + port + "/json", Detail.class).getBody();
// then
assertThat(detail.getSingleItemList().get(0)).isEqualTo(3);
}
}
If you use the Spring-approach keep in mind that you also can inject all those beans, they are created here straight-forward just show them better together. 如果您使用Spring方法,请记住您也可以注入所有这些bean,它们在此处直接创建的只是将它们更好地展示在一起。
You can also check this running example: 您还可以检查以下运行示例:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.