2011-04-18 11 views
8

Jaki jest najlepszy i najłatwiejszy sposób tworzenia fasoli w niestandardowy sposób (nie przez wywołanie konstruktora domyślnego) podczas deserializacji z JSON przy użyciu biblioteki Jackson? Zauważyłem, że istnieje interfejs JsonDeserializer, który mógłbym zaimplementować, ale nie jestem zbyt pewny, jak połączyć to wszystko w ObjectMapper.Jak utworzyć instancję fasoli w niestandardowy sposób z Jacksonem?

AKTUALIZACJA # 1: Myślę, że na moje pytanie potrzeba trochę więcej szczegółów. Domyślnie deserializator Jacksona używa domyślnego konstruktora do tworzenia fasoli. Chciałbym móc implementować tworzenie instancji komponentu bean, wywołując zewnętrzną fabrykę. Potrzebuję więc tylko klasy fasoli, która musi zostać utworzona. Fabryka zwróci instancję, która następnie może zostać przekazana Jacksonowi na popyt na nieruchomości i tak dalej.

Uwaga: nie martwię się o tworzenie prostych/skalarnych wartości, takich jak ciągi lub liczby, tylko fasola jest w obszarze moich zainteresowań.

Odpowiedz

0

można umieścić Deserializator na obiekt Java chcesz aby uzyskać json odwzorowywane na:

@JsonDeserialize(using = PropertyValueDeserializer.class) 
public class PROPERTY_VALUE implements Serializable{ 

a następnie w Deserializatora można na przykład zrobić:

@Override 
public PROPERTY_VALUE deserialize(JsonParser jsonParser, 
        DeserializationContext deserializationContext) 
      throws IOException, JsonProcessingException { 

    String tmp = jsonParser.getText(); // { 
    jsonParser.nextToken(); 
    String key = jsonParser.getText(); 
    jsonParser.nextToken(); 
    String value = jsonParser.getText(); 
    jsonParser.nextToken(); 
    tmp = jsonParser.getText(); // } 

    PROPERTY_VALUE pv = new PROPERTY_VALUE(key,value); 
    return pv; 
} 

Jeśli nie chcesz używać adnotacji, trzeba zdać mapowania DeserializerProvider które mogą zapewnić właściwą Deserializator dla danego typu.

mapper.setDeserializerProvider(myDeserializerProvider); 

Dla konstruktorów - oczywiście można wygenerować klasę docelową poprzez wywołanie fabryki w Deserializatora:

String value = jsonParser.getText(); 
    jsonParser.nextToken(); 
    tmp = jsonParser.getText(); // } 

    MyObject pv = MyObjectFactory.get(key); 
    pv.setValue(value); 
    return pv; 
} 

Ale może ja źle Twój aktualizacja

+0

Dzięki Heiko. Jackson domyślnie używa domyślnego konstruktora komponentu bean do utworzenia instancji. Chciałbym faktycznie utworzyć komponent bean za pomocą zewnętrznej fabryki. Zaktualizuję moje pytanie z pewnymi szczegółami w ciągu sekundy. –

+0

Jak mogłem to zrobić bez korzystania z adnotacji? –

+1

Używając adnotacji typu "mix-in", które nie muszą być dodawane bezpośrednio do samej klasy, ale do innych klas "mieszania". Dzięki temu można korzystać z adnotacji w bibliotekach firm trzecich. – StaxMan

8

Niektóre rzeczy, które mogą help ...

Po pierwsze, możesz użyć @JsonCreator do zdefiniowania alternatywnego konstruktora do użycia (wszystkie argumenty muszą być opatrzone adnotacją @JsonProperty, ponieważ kod bajtowy ma bez nazw) lub statyczną fabrykę. Wciąż będzie częścią klasy wartości, ale może pomóc w obsłudze niezmiennych obiektów.

Po drugie, jeśli chcesz naprawdę niestandardowy proces deserializacji, możesz sprawdzić http://wiki.fasterxml.com/JacksonHowToCustomDeserializers, który wyjaśnia, jak zarejestrować niestandardowe deserializatory.

Jedną z rzeczy, której obecnie brakuje Jacksonowi, jest obsługa obiektów w stylu budowniczym; istnieje żądanie zmiany funkcji, aby dodać wsparcie (i planuje się dodanie obsługi w przyszłości, gdy deweloperzy będą mieli czas).

Powiązane problemy