0

I've got two POJOs:

@lombok.Value
public class Foo {
  String foo;
  Bar bar;
}

@lombok.Value
public class Bar {
  String bar;
  String baz;
}

I'd like to be able to deserialize the following to a Foo instance:

{
  "foo": "some foo",
  "bar": "{ \"bar\": \"some bar\", \"baz\": \"some baz\" }"
}

If I understand it correctly this the exact opposite @JsonRawValue. There, it convert a Java String value (which is valid JSON value) to JSON object. But here, I need to convert a JSON string value to Java object.
I suspect that I need to write a custom deserializer, but I'm not sure how exactly since it involves parsing the raw JSON and assign it to the field. Maybe BeanDeserializerModifier? (I have no idea how to use it.)
I'd like to keep the object immutable (@Value), but I can drop this requirement if it helps solving the problem.
Thanks.

Rad
  • 4,292
  • 8
  • 33
  • 71
  • 1
    Does this answer your question? [Is it possible to make Jackson serialize a nested object as a string](https://stackoverflow.com/q/51141480/5221149) – Andreas Feb 17 '21 at 11:04
  • 1
    Take a look on this [answer](https://stackoverflow.com/a/66188646/51591). If you have `JSON` payload put as `String` into another `JSON` payload you need to deserialise it two times. First at root level, and next on escaped level. – Michał Ziober Feb 17 '21 at 12:12
  • Both questions are relevant, checking them. Thanks. – Rad Feb 17 '21 at 12:19

2 Answers2

0

if you use FooDto class delete this Bar bar; from DtoClass

or use this

@lombok.Value
public class Foo {
  String foo;
  @JsonIgnore
  Bar bar;
}
Abdalrhman Alkraien
  • 645
  • 1
  • 7
  • 22
0

With the help of this question mentioned by @Michał Ziober I managed to do it. Posting it here for reference since it was kinda tricky to get it working (with @Value and CamelCase property naming in JSON):

{
  "Foo": "some foo",
  "Bar": "{ \"bar\": \"some bar\", \"baz\": \"some baz\" }"
}

And the implementation is:

@Value
@Builder
@JsonDeserialize(builder = Foo.FooBuilder.class)
public class Foo {
    @JsonAlias("Foo") // note this!
    String foo;
    Bar bar;

    @JsonPOJOBuilder(withPrefix = "")
    public static class FooBuilder {
        @JsonAlias("Bar") // note this!
        @JsonDeserialize(using = BarDeserializer.class)
        public FooBuilder bar(Bar bar) {
            this.bar = bar;
            return this;
        }
    }
}

@lombok.Value
public class Bar {
  String bar;
  String baz;
}

public class BarDeserializer extends StdDeserializer<Bar> {
    public BarDeserializer() {
        super(Bar.class);
    }

    @Override
    public Bar deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
        return (Bar) ((ObjectMapper) p.getCodec()).readValue(p.getValueAsString(), _valueClass);
    }
}
Rad
  • 4,292
  • 8
  • 33
  • 71