Melina, miembro de nuestro equipo, nos hizo el favor de crear este tutorial ya que conoce a la perfección este tema.
Solución:
Actualizado 2018-11-10: Lombok 1.18.4 lanzado
Actualizado 2020-10-18: Lombok 1.18.16 lanzado
Lombok 1.18.16 contiene el nuevo @Jacksonized
anotación. Con él, simplemente puede escribir:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes(
@JsonSubTypes.Type(value = SubA.class),
@JsonSubTypes.Type(value = AnotherSub.class)
)
@Jacksonized
@SuperBuilder
// more annotations...
public abstract class AbstractA
@JsonProperty
protected final String superProperty;
@Jacksonized
@SuperBuilder
@JsonTypeName("SubA")
// more annotations...
public class SubA extends AbstractA
@JsonProperty
private final String fieldA;
Esto insertará automáticamente todas las anotaciones de Jackson necesarias y hará algunos ajustes en el constructor generado. Ya no es necesario personalizarlo.
Para antes Versiones de Lombok entre 1.18.4 y 1.18.12, Este es el camino a seguir:
Para Lombok’s @Builder
y @SuperBuilder
para trabajar con Jackson, debe agregar el encabezado de la clase de constructor manualmente y colocar un @JsonPOJOBuilder(withPrefix="")
en eso. Luego, Lombok generará solo el resto de la clase de constructor. Esto es necesario porque el valor predeterminado de Jackson es que los métodos de establecimiento del constructor tienen “con” como prefix, pero los constructores de Lombok no tienen prefix (y Lombok no es y probablemente nunca será configurable en este sentido).
Cuándo @SuperBuilder
se introdujo en Lombok 1.18.2, no era personalizable (es decir, no se podía agregar manualmente el encabezado de la clase del constructor). Como resultado, el uso @SuperBuilder
con Jackson no era fácilmente posible.
Esto cambió con Lombok 1.18.4 (consulte esta solicitud de extracción): @SuperBuilder
ahora es (al menos parcialmente) personalizable, y esto nos permite agregar la anotación. Tenga en cuenta que el código generado por @SuperBuilder
es bastante complejo y está muy cargado de genéricos. Para evitar estropear accidentalmente el código, debería echar un vistazo a la delombok generar y copiar / pegar el encabezado de la clase desde allí. Aquí, debe agregar el encabezado de la clase de implementación del constructor y poner la anotación en él:
@JsonPOJOBuilder(withPrefix="")
static final class SubABuilderImpl extends SubABuilder
Tenga en cuenta que debe ampliar la visibilidad de SubABuilderImpl
al menos al paquete-privado.
El @JsonDeserialize
La anotación también debe hacer referencia a la clase de implementación del constructor, no al constructor abstracto:
@JsonDeserialize(builder = SubA.SubABuilderImpl.class)
Una solución de trabajo en Eclipse, tenga en cuenta que la integración de Lombok IntelliJ no es compatible con todas las funciones, por lo tanto, el código se compila bien en Eclipse y con javac, pero IntelliJ cree que está roto pero ejecuta el código sin problemas.
public static ObjectMapper createObjectMapper()
final ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector()
@Override
public JsonPOJOBuilder.Value findPOJOBuilderConfig(final AnnotatedClass ac)
if (ac.hasAnnotation(JsonPOJOBuilder.class))
return super.findPOJOBuilderConfig(ac);
return new JsonPOJOBuilder.Value("build", "");
);
return mapper;
public static void main(final String[] args) throws Exception
final ObjectMapper objectMapper = createObjectMapper();
final String serializedForm = objectMapper.writeValueAsString(SubA.builder().build());
System.out.println(serializedForm);
final SubA anA = objectMapper.readValue(serializedForm, SubA.class);
System.out.println(anA);
@Getter
@EqualsAndHashCode(callSuper = true)
@Accessors(fluent = true, chain = true)
@SuperBuilder
@JsonDeserialize(builder = SubA.SubABuilderImpl.class)
@JsonTypeName("SubA")
public static class SubA extends AbstractA
@JsonProperty
private final String fieldA;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes(
@JsonSubTypes.Type(value = SubA.class)
)
@Getter
@Accessors(fluent = true, chain = true)
@SuperBuilder
public static abstract class AbstractA
@JsonProperty
protected final String superProperty;
Te invitamos a apoyar nuestra publicación mostrando un comentario o puntuándolo te damos la bienvenida.