Yves Calaci
Yves Calaci

Reputation: 1129

Jackson: "(although at least one Creator exists): no String-argument constructor/factory method to deserialize"

Altought the problem might sound simple, I'm facing this exception on a very simple bean as well:

@Data
public class Foo {
  private List<Error> errors;

  @Data
  public static class Error {
    private int code;
    private String message;
  }
}

The JSON:

{
  "errors": [
    "message": "bla bla bla"
  ]
}

The exception: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of "org.example.app.Foo$Error" (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('message')

The app:

@SpringBootApplication
public class Application {
  public static void main(String[] args) throws Exception {
    ApplicationContext context = SpringApplication.run(Application.class, args);
    ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
    Resource resource = new ClassPathResource("request.json");
    try (InputStream stream = resource.getInputStream()) {
        Foo foo = objectMapper.readValue(stream, Foo.class);
        System.out.println(foo);
    }
  }
}

The JSON file resides on the classpath.

What I've tried:

  1. Explicit @AllArgsConstructor Lombok annotation on Error class
  2. Switching from int code to Integer code (nullable type)
  3. Moving Error class out of Foo (non-inner class)

Upvotes: 13

Views: 50219

Answers (1)

Miron Balcerzak
Miron Balcerzak

Reputation: 926

Consider using @Jacksonized annotation with @Builder as per

https://projectlombok.org/features/experimental/Jacksonized

Fix your json object as well as it is malformed. "Errors" is using array of objects, so you should have something like:

{
    "errors": [{
        "message": "bla bla bla"
    }]
}

Upvotes: 7

Related Questions