Laurynas
Laurynas

Reputation: 1032

Java - Jackson Annotations to handle no suitable constructor

I am using Jackson ObjectMapper to read my response. Also I am using Spring ResponseErrorHandler to handle that response:

@Override
public void handleError(final ClientHttpResponse response) throws IOException {
objectMapper.readValue(response.getBody(), ServiceError.class);
}

I know that problem can by solved by adding default constructor, but I can't do that. I can't change ServiceError class at all.

Error got is this one:

No suitable constructor found for type ... can not instantiate fromJSON object(need to add/enable type information?)

Is there are any Jackson annotations to support such issue?

Upvotes: 1

Views: 472

Answers (2)

StaxMan
StaxMan

Reputation: 116522

Yes, if the class in question has suitable constructor to use, you can use @JsonCreator to indicate that that constructor is to be used. Also, if it takes multiple arguments, you will need to add @JsonProperty to indicate which JSON property should be mapped to which argument.

Upvotes: 2

Essex Boy
Essex Boy

Reputation: 7950

Define a JsonDeserializer

public class ServiceErrorSerializer extends JsonDeserializer<ServiceError> {

    @Override
    public ServiceError deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {

        ServiceError serviceError = new ServiceError(null, null);

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        serviceError.setName(node.get("name").asText());
        serviceError.setDescription(node.get("description").asText());

        return serviceError;

    }
}

Then register it with your objectMapper

@Test
public void test1() throws Exception {
    ServiceError serviceError = new ServiceError("Noby Stiles", "good footballer");
    serviceError.setName("Noby Stiles");
    serviceError.setDescription("good footballer");
    String json = new ObjectMapper().writeValueAsString(serviceError);

    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addDeserializer(ServiceError.class, new ServiceErrorSerializer());
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(simpleModule);

    ServiceError serviceError2 = objectMapper.readValue(json, ServiceError.class);
    assertNotNull(serviceError2);
    assertEquals("Noby Stiles", serviceError2.getName());
}

Upvotes: 2

Related Questions