2012-09-26 54 views
10

Tengo una clase con las siguientes anotaciones:Jersey/Jackson @JsonIgnore el colocador

class A { 
public Map<String,List<String>> references; 

@JsonProperty 
public Map<String,List<String>> getReferences() { 
... 
} 

@JsonIgnore 
public void setReferences(Map<String,List<String>>) { 
} 
... 
} 
} 

Lo que intento es hacer caso omiso de la JSON en deserialización. Pero no funciona. Siempre que llega JSON String, el Jackson lib llena el atributo de referencias. Si utilizo solo la anotación @JsonIgnore, el getter no funciona. ¿Hay alguna solución para este problema?

Gracias

Respuesta

0

sólo puedo pensar en una solución no-Jackson, de utilizar una clase base que no tiene referencias para el mapeo y luego arrojado a la clase real:

// expect a B on an incoming request 
class B { 
// ... 
} 

// after the data is read, cast to A which will have empty references 
class A extends B { 
public Map<String,List<String>> references; 
} 

¿Por qué incluso envías las referencias si no las quieres?

¿O los datos entrantes están fuera de sus manos y solo desea evitar la excepción de asignación que le indica que jackson no puede encontrar una propiedad para establecer para las referencias entrantes? Para que utilizamos una clase base que todas nuestras clases del modelo Json heredan:

public abstract class JsonObject { 

    @JsonAnySetter 
    public void handleUnknown(String key, Object value) { 

     // for us we log an error if we can't map but you can skip that 
     Log log = LogFactory.getLog(String.class);  
     log.error("Error mapping object of type: " + this.getClass().getName());  
     log.error("Could not map key: \"" + key + "\" and value: \"" + "\"" + value.toString() + "\""); 

    } 

Luego, en el POJO que añadir @JsonIgnoreProperties por lo que las propiedades entrantes son reexpedidos a handleUnknown()

@JsonIgnoreProperties 
class A extends JsonObject { 
    // no references if you don't need them 
} 

Editar

This SO Thread describe cómo usar Mixins. Esta podría ser la solución, si desea mantener su estructura exactamente como está, pero no lo he intentado.

+0

Así es. La información entrante no está realmente en nuestras manos. Pero el cliente envía siempre el atributo de referencias en el formato correcto para que nunca se invoque handleUnknown. – guerilla

+0

Ah, mi mal, olvidé un poco de información. Necesitas '@ JsonIgnoreProperties' en el POJO si quieres ignorar los datos entrantes. Actualizaré mi publicación. (PD: usamos esto para consumir el recurso REST de Facebook y todas las propiedades enviadas desde Facebook que no están contenidas en nuestro POJO se registrarán y luego decidiremos si queremos agregarlas o no) – Pete

+0

Pero las referencias están en mi POJO por lo que siempre coincide con el colocador – guerilla

15

Creo que hay dos piezas clave que deberían permitirle tener "colecciones de solo lectura" si lo desea. En primer lugar, además de ignorar el organismo, asegúrese de que su campo también está marcado con @JsonIgnore:

class A { 

    @JsonIgnore 
    public Map<String,List<String>> references; 

    @JsonProperty 
    public Map<String,List<String>> getReferences() { ... } 

    @JsonIgnore 
    public void setReferences(Map<String,List<String>>) { ... } 

} 

En segundo lugar, con el fin de evitar que los captadores de ser utilizado como fijadores, desactivar la función USE_GETTERS_AS_SETTERS:

ObjectMapper mapper = new ObjectMapper(); 
mapper.disable(MapperFeature.USE_GETTERS_AS_SETTERS); 
+0

Inegablemente ignoré su primer consejo y no marqué el campo como ignorado, ya que es privado en mi caso. Sin embargo, necesitaba hacerlo, sin embargo, para que funcione correctamente. ¿Es esto correcto o un malentendido de mi parte? Si es así, tal vez valga la pena señalarlo explícitamente en su respuesta. –

4

Debes asegurarte de que haya una anotación @JsonIgnore en el nivel de campo, así como en el colocador, y getter anotado con @JsonProperty.

public class Echo { 

    @Null 
    @JsonIgnore 
    private String doNotDeserialise; 

    private String echo; 

    @JsonProperty 
    public String getDoNotDeserialise() { 
     return doNotDeserialise; 
    } 

    @JsonIgnore 
    public void setDoNotDeserialise(String doNotDeserialise) { 
     this.doNotDeserialise = doNotDeserialise; 
    } 

    public String getEcho() { 
     return echo; 
    } 

    public void setEcho(String echo) { 
     this.echo = echo; 
    } 
} 

@Controller 
public class EchoController { 

@ResponseBody 
@RequestMapping(value = "/echo", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) 
    public Echo echo(@RequestBody @Valid Echo echo) { 
     if (StringUtils.isEmpty(echo.getDoNotDeserialise())) { 
      echo.setDoNotDeserialise("Value is set by the server, not by the client!"); 
     } 

     return echo; 
    } 
} 
  • Si envía una solicitud JSON con un valor de “doNotDeserialise” ajustado a algo, cuando JSON se deserialised a un objeto que se establece en null (si no pongo una restricción de validación en el campo por lo será de error out)
  • Si se establece el valor “doNotDeserialise” a algo en el servidor a continuación, se puede serializar correctamente a JSON y empujado al cliente
3

que utilizan @JsonIgnore en mi getter y que dejase' t trabajo y no pude configurar el asignador (I w como usar proveedores de Jackson Jaxrs).Esto funcionó para mí:

@JsonIgnoreProperties(ignoreUnknown = true, value = { "actorsAsString", 
    "writersAsString", "directorsAsString", "genresAsString" }) 
0

A partir de Jackson 2.6, hay una manera nueva y mejorada para definir read-only y write-only propiedades, utilizando JsonProperty#access() anotación. Esto se recomienda sobre el uso de anotaciones separadas de JsonIgnore y JsonProperty.

@JsonProperty(access = JsonProperty.Access.READ_ONLY) 
public Map<String,List<String>> references; 
Cuestiones relacionadas