Adam
Adam

Reputation: 525

spring-boot jackson single object as array

I am having an issue with resolving a single object as an array I have used the following property

# JACKSON (JacksonProperties).
spring.jackson.deserialization.ACCEPT_SINGLE_VALUE_AS_ARRAY=true

In addition to the above I have configured a rest template as follows:

@Test
    public void testSingleObject() {
        RestTemplate restTemplate = new RestTemplate();
         ObjectMapper mapper = new ObjectMapper();
        MappingJackson2HttpMessageConverter convertor = new MappingJackson2HttpMessageConverter();
        convertor.setObjectMapper(mapper);
        mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
        restTemplate.getMessageConverters().add(convertor);
        MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
        mockServer.expect(requestTo("/test/1")).andExpect(method(HttpMethod.GET))
                .andRespond(withSuccess("{\"size\":\"1\",\"Value\":{\"@id\": \"1\",\"description\":\"Some Text\"}}", MediaType.APPLICATION_JSON));
       // JsonNode jsonNode = restTemplate.getForObject("/test/{id}", JsonNode.class, 1);
        mycalss value = restTemplate.getForObject("/test/{id}", myclass.class, 1);
        System.out.print(value.toString());
    }

I am using spring-boot 1.3.2, the error I get is

Could not read document: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

Ps: If I try this without rest template it works as expected

@Test
    public void testSingleObject3() throws IOException {
        final String json = "{\"size\":\"1\",\"Value\":{\"@id\": \"1\",\"description\":\"Some Text\"}}";

        final ObjectMapper mapper = new ObjectMapper()
                .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
        myclass value = mapper.readValue(json,
                new TypeReference<myclass>() {
        });
        System.out.println(value.toString());
    }

my class is defined a follows :

//@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class myclass {
@JsonProperty("size")
private String Size;
@JsonProperty("value")
private List<mysubclass> mysubclass;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>(); 
//... setters and getters 

mysubclass is defined as follows:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"id",
"description"
})
public class mysubclass {

@JsonProperty("@id")
private String Id;
@JsonProperty("description")
private String description;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

Regards

Upvotes: 4

Views: 3833

Answers (1)

mzc
mzc

Reputation: 3355

When you do

restTemplate.getMessageConverters().add(converter);

you're actually adding a second jackson converter to the RestTemplate's list of converters.

When you run the code, the first one (which was added by default by the RestTemplate constructor) is being used so it doesn't matter that you've configured the second one.

If you change that piece of code to

restTemplate.setMessageConverters(Collections.singletonList(converter));

the default converters will be discarded and only the one you've configured will be used.

Upvotes: 2

Related Questions