1

I need to deserialize a yml file into a Java object which does not have a default constructor. This causes Jackson's ObjectMapper to complain and throw an exception.

The Java class in particular is not my own (it's a dependency), so I cannot modify it. The author's idea for the class is to construct objects using the Builder Pattern and has not provided a default constructor.

In order to circumvent the issue I would need to create an adapter class, I suppose. Then I would build my object by using the serialized adapter object and filling in the builder.

Is there any cleaner way to do this? If only ObjectMapper provided methods to read from a stream into a specific object, I could make an empty object using the builder and then fill it up with Jackson...

Mr. Nicky
  • 1,519
  • 3
  • 18
  • 34
  • 1
    Have you looked into a [custom deserializer](https://stackoverflow.com/questions/19158345/custom-json-deserialization-with-jackson)? – ernest_k Jan 03 '19 at 14:42
  • `@JsonCreator` also comes to mind – Dargenn Jan 03 '19 at 14:44
  • The problematic class is not my own, it's a dependency (spring to be precise), so I cannot modify it. – Mr. Nicky Jan 03 '19 at 14:47
  • 1
    Possible duplicate of [How to de/serialize an immutable object without default constructor using ObjectMapper?](https://stackoverflow.com/questions/30568353/how-to-de-serialize-an-immutable-object-without-default-constructor-using-object) – locus2k Jan 03 '19 at 14:58
  • Try creating a plain Java class that has the structure of your input and try deserializing to that. If that works, you could then build an instance of the class you actually want. Sometimes, the straightforward solution is the best. – Steve11235 Jan 03 '19 at 15:00
  • Can you give us the name of the java class you're trying to fill ? In order to make some tests – Julien Revault d'A... Jan 03 '19 at 15:23
  • Here you go: https://docs.spring.io/spring-cloud-open-service-broker/docs/current/apidocs/org/springframework/cloud/servicebroker/model/catalog/Catalog.html – Mr. Nicky Jan 03 '19 at 15:24

2 Answers2

1

This is just an expanded version of the @Steve11235 comment.

This is not an adaptor, it is just a workaround.

  1. Create a class that matches the JSON format; I will call this Blammy.
  2. Include a method in the Blammy class to populate the Builder for the desired actual class; I will call this Blammy.builderate(DesiredBuilder)
  3. Use jackson to deserialize the JSON into the Blammy class.
  4. Post deserialization, create the desired Builder and pass it to the Blammy.builderate() method.
DwB
  • 37,124
  • 11
  • 56
  • 82
0

Okay, so what I ended up doing is I loaded up the YAML file into Jackson's ObjectMapper. Then I traversed the resulting JsonNode object which represents the whole structure of the YAML file and then generically passed in the parameters to the builder class.

Mr. Nicky
  • 1,519
  • 3
  • 18
  • 34