Chciałbym, aby Jackson deserializował klasę za pomocą następującego konstruktora:
public Clinic(String name, Address address)
Deserializacja pierwszego argumentu jest łatwa. Problem polega na tym, że adres jest zdefiniowany jako:
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();
}
}
i jest zbudowany w następujący sposób: new Address.Builder().setCity("foo").setCountry("bar").create();
Czy istnieje sposób na uzyskanie par klucz-wartość od Jacksona w celu samodzielnego skonstruowania adresu? Alternatywnie, czy jest sposób, aby Jackson użył samej klasy Builder?
@JsonPOJOBuilder
wszystkich adnotacji razem, zmień nazwę „utwórz” na „buduj” i dodaj adnotację do każdego ustawiacza budującego@JsonProperty
.@Jacksonized
który zastępuje wewnętrznego konstruktora i adnotacje@Jackonized
jest właśnie wydaną eksperymentalną funkcją w Lombok. Nie sądzę, aby niepotrzebne zachęcanie do przyjmowania funkcji eksperymentalnych było dobrym pomysłem. b) pytanie nie wspomina ani nie używa Lombok. Uważam, że niepotrzebne wprowadzanie zależności w celu rozwiązania problemu nie jest dobrym pomysłem.Odpowiedź od @Rupert Madden-Abbott działa. Jeśli jednak masz konstruktor inny niż domyślny, np.
Następnie powinieneś opisać parametry jak poniżej:
@JsonCreator Builder(@JsonProperty("city") String city, @JsonProperty("country") String country) {...}
źródło
Rozwiązanie, które było dla mnie odpowiednie w tym przypadku (użyłem adnotacji budowniczego "Lombok").
@Getter @Builder(builderMethodName = "builder") @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PRIVATE) @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.ANY, creatorVisibility = JsonAutoDetect.Visibility.ANY )
Mam nadzieję, że tobie też się przyda.
źródło
@Jacksonized
który zastępuje wewnętrznego konstruktora i adnotacjeSkończyło się na implementacji tego przy użyciu @JsonDeserialize w następujący sposób:
@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(); } }
źródło
Obecnie nie ma wsparcia dla wzorca buildera, chociaż został o to poproszony już jakiś czas temu (i wreszcie został zgłoszony numer Jira http://jira.codehaus.org/browse/JACKSON-469 ) - to coś, co można dodać na wydanie 1.8, jeśli jest wystarczające zapotrzebowanie (koniecznie zagłosuj w Jira!). Jest to rozsądna dodatkowa funkcja, opóźniona tylko o czas, jaki mają programiści. Ale myślę, że byłby to świetny dodatek.
źródło
To zadziałało dla mnie: @NoArgsConstructor Jedyną wadą tego jest to, że można ponownie wykonać = new ADTO (). Ale, hej, i tak nie lubię policji kodującej, mówiąc mi, jak używać czyjegoś kodu :-) Więc używaj mojego POJO DTOS tak, jak lubisz. Z konstruktorem lub bez niego. Proponuję: zrób to z Konstruktorem, ale bądź moim gościem ...
@Data @Builder //Dont forget this! Otherwise no Jackson serialisation possible! @NoArgsConstructor @AllArgsConstructor public class ADTO { ..... }
źródło