Modo de empleo Jackson deserializar la clase constructor externo Lombok

pscl:

Tengo una tercera parte de Lombok constructor POJO, uno que no puedo modificar, que quiero serializar el uso de Jackson. Cabe destacar que lo hace no tiene un NoArgsConstructor.

@Data
@Builder
public class ExternalClass {
   private String name;
   private String data; 
   // etc.
} 

En la superficie esto parece ser simple, pero es muy frustrante, en la práctica, ya que cada opción posible parece ser contrarrestada por una complicación diferente. En esencia, estoy teniendo problemas para conseguir una externa Lombok constructor de trabajo con un Jackson mixin .

Lombok produce emisores de fluidez del estilo .name(String name)mientras que Jackson incorporado en Espera constructor deserializador .withName(String name). Documentación Lombok, y recetas en otro lugar tal como aquí sugieren el uso @JsonDeserialize(builder=ExternalClass.ExternalClassBuilder.class)en conjunción con @JsonPOJOBuilder(withPrefix="")un constructor de talón interior predeclared. Pero esto no es posible porque la clase Lombok se encuentra en una biblioteca externa.

La aplicación de estas anotaciones a un mixin no tiene ningún efecto.

@JsonDeserialize(ExternalClass.ExternalClassBuilder.class)
public abstract class ExternalClassMixin {
   @JsonPOJOBuilder(withPrefix="")
   public static ExternalClassBuilder {
   }
} 

El único enfoque que he encontrado que funciona es la de aprovechar el paquete de acceso AllArgsConstructor creada por @Buildery poblar el mixin con el siguiente constructor

public abstract class ExternalClassMixin {
   @JsonCreator public ExternalClassMixin(
      @JsonProperty("name") String name,
      @JsonProperty("data") String data,
      // etc.
  ) {} 
} 

Esto obviamente no es deseable, ya que requiere la iteración y la codificación dura de todas las propiedades de clase de forma explícita, haciendo que el mixin frágil a cualquier cambio en el POJO externa.

Mi pregunta es - ¿hay una manera robusta, fácil de mantener para serializar esta clase constructor externo utilizando Jackson sin modificarlo, utilizando un mixin o tal vez un deserializer completo soplado?

Actualizar

He implementado la excelente respuesta por @ Jan-Rieke, incluyendo la sugerencia de utilizar la reflexión para buscar a la clase constructor interior.

...
public Class<?> findPOJOBuilder(AnnotatedClass ac) {
   Class<?> innerBuilder;
   try {
      innerBuilder = Class.forName(ac.getName()+"$"+ac.getRawType().getSimpleName()+"Builder");
      log.info("Builder found: {}", ac.getName());
      return innerBuilder;
   } catch( ClassNotFoundException e ) {
      return super.findPOJOBuilder(ac);
   }
}
Ene Rieke:

Puede personalizar la ObjectMapperforma siguiente:

    ObjectMapper mapper = new ObjectMapper();
    mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
        @Override
        public Class<?> findPOJOBuilder(AnnotatedClass ac) {
            if (ExternalClass.class.equals(ac.getRawType())) {
                return ExternalClass.ExternalClassBuilder.class;
            }
            return super.findPOJOBuilder(ac);
        }

        @Override
        public Value findPOJOBuilderConfig(AnnotatedClass ac) {
            if (ac.hasAnnotation(JsonPOJOBuilder.class)) {
                return super.findPOJOBuilderConfig(ac);
            }
            return new JsonPOJOBuilder.Value("build", "");
        }
    });

Esta voluntad

  • configurar explícitamente que deserialización para ExternalClassusos su constructor, y
  • establecer el prefijo por defecto para Builder métodos setter a ""(excepto cuando la @JsonPOJOBuilderanotación está presente).

Si no desea ver todas las clases externas explícitamente en findPOJOBuilder(), puede, por supuesto, mediante programación mirar en la clase para comprobar si tiene una clase interna que se parece a un constructor.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=189797&siteId=1
Recomendado
Clasificación