2011-08-18 12 views
136

Domyślne działanie jackonu wydaje się używać obu właściwości (pobierających i ustawiających) i pól do serializowania i deserializacji do json.jak określić jackson, aby używać tylko pól - najlepiej globalnie

Chciałbym użyć pól jako kanonicznego źródła konfiguracji serializacji, a tym samym nie chcę, aby jackson w ogóle patrzył na właściwości.

mogę to zrobić na zasadzie indywidualnej klasy z adnotacją:

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) 

Ale ja nie chcę umieścić to na każdej klasie ...

Czy jest możliwe skonfigurować to globalnie? Jak dodać niektóre do Object Mapper?

+1

Tim dał dobrą odpowiedź. Inną możliwością jest to, że jeśli masz wspólną klasę podstawową, możesz umieścić adnotacje klas do tego; adnotacje są dziedziczone przez Jacksona. – StaxMan

+1

Myślę, że próbowałem, ale wydaje się, że musisz powiedzieć subklasom, aby użyć tego, co definiuje podstawowy kod ... –

+2

Nie, chyba że podklasa zastępuje adnotację klasy, adnotacje rodziców są widoczne tak, jakby były częścią podrzędnych definicja klasy (jeśli nie, byłby to błąd). Niekoniecznie jest to sposób, w jaki JDK radzi sobie z adnotacjami, ale Jackson stosuje pełne dziedziczenie dla adnotacji (nawet dla adnotacji metod). – StaxMan

Odpowiedz

117

Można skonfigurować poszczególne ObjectMappers tak:

ObjectMapper mapper = new ObjectMapper(); 
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker() 
       .withFieldVisibility(JsonAutoDetect.Visibility.ANY) 
       .withGetterVisibility(JsonAutoDetect.Visibility.NONE) 
       .withSetterVisibility(JsonAutoDetect.Visibility.NONE) 
       .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)); 

Jeśli chcesz go ustawić globalnie, zwykle dostęp do skonfigurowanego mapowania przez klasy otoki.

+3

Dobrze, chociaż myślę, że być może będziesz musiał ustawić także kontroler (zXX() metody zwykle tworzą nowy obiekt). A więc coś w rodzaju "mapper.setVisibilityChecker (mapper.getVisibilityChecker(). With ...);" – StaxMan

+0

@StaxMan good call na setVisibilityChecker, edytowałem odpowiedź, aby odzwierciedlić. –

+32

'withGetterVisibility' nie obejmuje metod' is * ', ale jest w nich' withIsGetterVisibility'. – qerub

103

w Jackson 2.0 i później można po prostu użyć:

import com.fasterxml.jackson.annotation.JsonAutoDetect; 
import com.fasterxml.jackson.annotation.PropertyAccessor; 
import com.fasterxml.jackson.databind.ObjectMapper; 

... 

ObjectMapper mapper = new ObjectMapper();  
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); 
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); 

aby wyłączyć automatyczne wykrywanie.

+1

Witajcie, Używam pliku Jackson 1.9.0 jar. Otrzymuję dodatkową właściwość json, podczas serializacji obiektu do łańcucha json. Potrzebuję uzyskać ciąg json, który zawiera tylko wymienione zmienne z @JsonProperty. Czy możesz mi pomóc w tej sprawie? – jrhamza

+6

Możesz zacząć od adnotacji klasy wspomnianej w pytaniu OP: '@JsonAutoDetect (fieldVisibility = Visibility.NONE, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)' Następnie musisz dodać adnotację do każdej właściwości, którą chcesz dołączyć do '@ JsonProperty' – lukk

10

dla Jacksona 1.9.10 Używam

ObjectMapper mapper = new ObjectMapper(); 

mapper.setVisibility(JsonMethod.ALL, Visibility.NONE); 
mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); 

włączyć auto dedection.

+1

To jest sposób. Dzięki. – cuneytykaya

+0

Zastanawiam się, czy jest jakaś różnica między zrobieniem tego i wyłączeniem "auto wykrywa". – xenoterracide

22

Mam spędzić dużo czasu: dlaczego ani

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) 

nie

setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE); 
    setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE); 
    setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); 

nie działa dla mojego logicznego getter/setter. Rozwiązanie jest simpe:

@JsonAutoDetect(isGetterVisibility = Visibility.NONE, ...   
    setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE); 
+0

Czy mógłbyś wyjaśnić, jak proste powinno być zastosowanie rozwiązania w klasie fasoli? –

+1

Dziękuję. To znaczy, że Gets uratował mi dzień. – grinch

7

Jak o tym: Używałem go z wstawek

niezgodna obiekt

@Entity 
@Getter 
@NoArgsConstructor 
public class Telemetry { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long pk; 
    private String id; 
    private String organizationId; 
    private String baseType; 
    private String name; 
    private Double lat; 
    private Double lon; 
    private Instant updateTimestamp; 
} 

mixin:

@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE) 
public static class TelemetryMixin {} 

Zastosowanie:

ObjectMapper om = objectMapper.addMixIn(Telemetry.class, TelemetryMixin.class); 
    Telemetry[] telemetries = om.readValue(someJson, Telemetry[].class); 

Nic nie wskazuje na to, że nie można pominąć żadnej liczby klas i zastosować tego samego mixin.

Jeśli nie jesteś zaznajomiony z mixinami, są one koncepcyjnie proste: struktura mixin jest super nałożona na klasę docelową (zgodnie z jackson, nie aż do JVM).

Powiązane problemy