1

I tried to implement the equivalent of Jacksons's @JsonUnwrapped in Jsonb (using Yasson) with this:

@Retention(RetentionPolicy.RUNTIME)
@JsonbTypeSerializer(UnwrappedJsonbSerializer.class)
public @interface JsonbUnwrapped {}

public class UnwrappedJsonbSerializer implements JsonbSerializer<Object> {

    @Override
    public void serialize(Object object, JsonGenerator generator, SerializationContext context) {
        context.serialize(object, new UnwrappedJsonGenerator(generator));
    }
}

public class UnwrappedJsonGenerator extends JsonGeneratorWrapper {

    private int level;

    public UnwrappedJsonGenerator(JsonGenerator delegate) {
        super(delegate);
    }

    @Override
    public JsonGenerator writeStartObject(String name) {
        return level++ == 0 ? this : super.writeStartObject(name);
    }

    @Override
    public JsonGenerator writeStartArray(String name) {
        return level++ == 0 ? this : super.writeStartArray(name);
    }

    @Override
    public JsonGenerator writeEnd() {
        return --level == 0 ? this : super.writeEnd();
    }
}

public class Person {

    @JsonbUnwrapped
    public Name getName() {
        return new Name();
    }

    public static class Name {

        public String getFirstName() {
            return "John";
        }

        public String getLastName() {
            return "Doe";
        }
    }
}

JsonbBuilder.create().toJson(new Person())

But this raises an exception javax.json.bind.JsonbException: Recursive reference has been found in class class Person$Name because my UnwrappedJsonbSerializer calls SerializationContext.serialize() with the same object that was initially passed.

Is there any other way to achieve that without resorting to custom serializers for Person or Name ?

Xavier Dury
  • 1,530
  • 1
  • 16
  • 23

0 Answers0