Me gustaría que Jackson deserializara una clase con el siguiente constructor:
public Clinic(String name, Address address)
Deserializar el primer argumento es fácil. El problema es que Dirección se define como:
public class Address {
private Address(Map<LocationType, String> components)
...
public static class Builder {
public Builder setCity(String value);
public Builder setCountry(String value);
public Address create();
}
}
y se construye así: new Address.Builder().setCity("foo").setCountry("bar").create();
¿Hay alguna manera de obtener pares clave-valor de Jackson para construir la Dirección yo mismo? Alternativamente, ¿hay alguna manera de hacer que Jackson use la clase Builder?
@JsonPOJOBuilder
anotación por completo, cambie el nombre de "crear" a "construir" y anote cada uno de los creadores de constructores con@JsonProperty
.@Jacksonized
que reemplaza el constructor interno y las anotaciones de@Jackonized
es una función experimental recién lanzada en Lombok. No creo que sea una buena idea fomentar innecesariamente la adopción de funciones experimentales. b) la pregunta no menciona ni usa Lombok. No creo que sea una buena idea introducir innecesariamente una dependencia para resolver un problema.La respuesta de @Rupert Madden-Abbott funciona. Sin embargo, si tiene un constructor no predeterminado, por ejemplo,
Luego, debe anotar los parámetros de la siguiente manera:
@JsonCreator Builder(@JsonProperty("city") String city, @JsonProperty("country") String country) {...}
fuente
Una solución que fue adecuada para mí en este caso (utilicé la anotación del constructor "Lombok").
@Getter @Builder(builderMethodName = "builder") @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PRIVATE) @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.ANY, creatorVisibility = JsonAutoDetect.Visibility.ANY )
Espero que también te sea útil.
fuente
@Jacksonized
que reemplaza el constructor interno y las anotaciones deTerminé implementando esto usando @JsonDeserialize de la siguiente manera:
@JsonDeserialize(using = JacksonDeserializer.class) public class Address {...} @JsonCachable static class JacksonDeserializer extends JsonDeserializer<Address> { @Override public Address deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { JsonToken token = parser.getCurrentToken(); if (token != JsonToken.START_OBJECT) { throw new JsonMappingException("Expected START_OBJECT: " + token, parser.getCurrentLocation()); } token = parser.nextToken(); Builder result = new Builder(); while (token != JsonToken.END_OBJECT) { if (token != JsonToken.FIELD_NAME) { throw new JsonMappingException("Expected FIELD_NAME: " + token, parser.getCurrentLocation()); } LocationType key = LocationType.valueOf(parser.getText()); token = parser.nextToken(); if (token != JsonToken.VALUE_STRING) { throw new JsonMappingException("Expected VALUE_STRING: " + token, parser.getCurrentLocation()); } String value = parser.getText(); // Our Builder allows passing key-value pairs // alongside the normal setter methods. result.put(key, value); token = parser.nextToken(); } return result.create(); } }
fuente
Actualmente no hay soporte para el patrón del constructor, aunque se solicitó hace bastante tiempo (y finalmente se archivó el problema de Jira http://jira.codehaus.org/browse/JACKSON-469 ); es algo que se puede agregar para la publicación 1.8 si hay suficiente demanda (¡asegúrese de votar en Jira!). Es una característica adicional razonable y solo se retrasa por la cantidad de tiempo que tienen los desarrolladores. Pero creo que sería una gran adición.
fuente
Esto funcionó para mí: @NoArgsConstructor El único inconveniente de esto es que uno puede hacer = new ADTO () nuevamente. Pero, oye, de todos modos no me gusta la policía de códigos, que me dice cómo usar el código de alguien :-) Entonces, usa mi POJO DTOS de la manera que te guste. Con o sin constructor. Sugiero: hazlo con un constructor, pero sé mi invitado ...
@Data @Builder //Dont forget this! Otherwise no Jackson serialisation possible! @NoArgsConstructor @AllArgsConstructor public class ADTO { ..... }
fuente