Gostaria que Jackson desserialize uma classe com o seguinte construtor:
public Clinic(String name, Address address)
Desserializar o primeiro argumento é fácil. O problema é que o endereço é definido 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();
}
}
e é construído assim: new Address.Builder().setCity("foo").setCountry("bar").create();
Existe uma maneira de obter pares de valores-chave de Jackson para construir o endereço sozinho? Como alternativa, há uma maneira de fazer com que Jackson use a própria classe Builder?
@JsonPOJOBuilder
anotação por completo, renomeie "criar" para "construir" e anote cada um dos configuradores do construtor com@JsonProperty
.@Jacksonized
que substitui o construtor interno e as anotações de jackson por uma única coisa@Jackonized
é um recurso experimental recém-lançado no Lombok. Não acho que seja uma boa ideia encorajar desnecessariamente a adoção de recursos experimentais. b) a pergunta não menciona ou usa o Lombok. Não acho uma boa ideia introduzir desnecessariamente uma dependência para resolver um problema.A resposta de @Rupert Madden-Abbott funciona. No entanto, se você tiver um construtor não padrão, por exemplo,
Então você deve anotar os parâmetros como abaixo:
@JsonCreator Builder(@JsonProperty("city") String city, @JsonProperty("country") String country) {...}
fonte
Uma solução adequada para mim neste caso (usei a anotação de construtor "Lombok").
@Getter @Builder(builderMethodName = "builder") @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PRIVATE) @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.ANY, creatorVisibility = JsonAutoDetect.Visibility.ANY )
Espero que seja útil para você também.
fonte
@Jacksonized
que substitui o construtor interno e as anotações de jackson por uma única coisaAcabei implementando isso usando o @JsonDeserialize da seguinte maneira:
@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(); } }
fonte
Não há suporte atualmente para o padrão do construtor, embora tenha sido solicitado há algum tempo (e finalmente o problema Jira http://jira.codehaus.org/browse/JACKSON-469 foi arquivado) - é algo que pode ser adicionado para versão 1.8 se houver demanda suficiente (certifique-se de votar em Jira!). É um recurso adicional razoável, e apenas atrasado pelo tempo que os desenvolvedores têm. Mas acho que seria uma ótima adição.
fonte
Isso funcionou para mim: @NoArgsConstructor A única desvantagem disso é que se pode fazer o = new ADTO () novamente. Mas, hey, eu não gosto da polícia de código de qualquer maneira, me dizendo como usar o código de alguém :-) Então, use meu POJO DTOS do jeito que você gosta. Com ou sem construtor. Sugiro: faça com um Construtor, mas fique à vontade ...
@Data @Builder //Dont forget this! Otherwise no Jackson serialisation possible! @NoArgsConstructor @AllArgsConstructor public class ADTO { ..... }
fonte