Saltar al contenido

Ejemplo de Lombok @SuperBuilder con anotaciones json

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *