2011-08-18 15 views
136

El comportamiento predeterminado de jackon parece usar tanto las propiedades (getters y setters) como los campos para serializar y deserializar a json.cómo especificar que jackson solo use campos: preferiblemente globalmente

Me gustaría utilizar los campos como la fuente canónica de configuración de serialización y, por lo tanto, no quiero que jackson mire propiedades en absoluto.

puedo hacer esto sobre una base de clase individual con la anotación:

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

Pero yo no quiero tener que poner esto en cada clase única ...

¿Es posible configurar esto globalmente? ¿Como agregar algo al Object Mapper?

+1

Tim dio una buena respuesta. Otra posibilidad es que si tienes una clase base común, puedes poner anotaciones de clase a esa; las anotaciones son heredadas por Jackson. – StaxMan

+1

Creo que lo intenté, pero parece que tienes que decir a las subclases que usen lo que el caso base define ... –

+2

No, a menos que la subclase anule la anotación de clase, las anotaciones de los padres son visibles como si fueran parte de una subclase. definición de clase (si no, esto sería un error). Esta no es necesariamente la forma en que JDK trata las anotaciones, pero Jackson implementa la herencia completa para las anotaciones (incluso para las anotaciones de métodos). – StaxMan

Respuesta

117

Puede configurar ObjectMappers individuales como esto:

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)); 

Si lo desea establecer de forma global, por lo general tener acceso a un mapeador configurado a través de una clase de contenedor.

+3

Bueno, aunque creo que es posible que deba configurar también el comprobador (con los métodos Xxx() generalmente se crea un nuevo objeto). Algo así como 'mapper.setVisibilityChecker (mapper.getVisibilityChecker(). With ...);' – StaxMan

+0

@StaxMan buena llamada en setVisibilityChecker, edité la respuesta para reflejar. –

+32

'withGetterVisibility' no cubre los métodos' is * ', pero hay' withIsGetterVisibility' para ellos. – qerub

103

en Jackson 2.0 y posteriores puede simplemente usar:

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); 

para desactivar la detección automática.

+1

Hola chicos, Estoy usando Jackson 1.9.0 jar. Obtengo una propiedad json adicional, mientras serializo el objeto a la cadena json. Necesito obtener la cadena json, que contiene solo las variables mencionadas con @JsonProperty. ¿Puede ayudarme en esto? – jrhamza

+6

Puede comenzar con la anotación de clase mencionada en la pregunta OP: '@JsonAutoDetect (fieldVisibility = Visibility.NONE, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)' A continuación, debe anotar cada propiedad que desea incluir con '@ JsonProperty' – lukk

10

para Jackson 1.9.10 utilizo

ObjectMapper mapper = new ObjectMapper(); 

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

a su vez de dedection automático.

+1

Ese es el camino. Gracias. – cuneytykaya

+0

se pregunta si hay alguna diferencia entre hacer esto y deshabilitar el "auto detecta". – xenoterracide

22

he pasar mucho tiempo: por qué ni

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

sin

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

no funciona para mi booleano captador/definidor. solución es simpe:

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

¿Podría explicarnos cómo debería aplicarse la solución simple a la clase Bean? –

+1

Gracias. Eso es que Getter me salvó el día. – grinch

7

¿Qué tal esto: Lo utilicé con un mixin

no conforme objeto

@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 {} 

Uso:

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

No hay nada que diga que no se puede evitar ninguna cantidad de clases y aplicar la misma mezcla.

Si no está familiarizado con mixins, son conceptualmente simple: La estructura del mixin es súper impuesta en la clase de objetivo (de acuerdo con Jackson, no tan lejos como la JVM se refiere).

Cuestiones relacionadas