2011-12-01 11 views
6

Con la biblioteca Jackson json, es posible deserializar el objeto mediante el uso del @JsonCreator, y se le dará el mapa de "nivel superior" que representa la entrada json, como sigue:Utilice @JacksonInject con @JsonCreator en un mapa de nivel superior

class MyClass { 
    final int field; 

    @JsonCreator 
    public MyClass(Map<String, Object> map) { 
     this.field = (int) map.get("theInt"); 
    } 
} 

o incluso en un método de fábrica estática:

class MyClass { 
    final int field; 

    public MyClass(int theInt) { 
     this.field = theInt; 
    } 

    @JsonCreator 
    static MyClass create(Map<String, Object> map) { 
     return new MyClass((int) map.get("theInt")); 
    } 
} 

los ejemplos anteriores pueden procesar los siguientes tipos de entrada de JSON:

{ 
    "key1":"value1", 
    "key2":"value2", 
    "key3":"value3" 
} 

Esto es particularmente útil en mi caso porque me gustaría deserializar una estructura json que no sé. Tener acceso a lo que llamo el "mapa de nivel superior" hace las cosas simples.

Me gustaría deserializar mis objetos de esta manera, ya que también permite crear objetos inmutables, en lugar de usar @JsonAnySetter que no lo permite, y @JsonProperty que no puedo usar ya que no conozco el nombre de las propiedades de antemano como he mencionado anteriormente.

Luego de ir más lejos, me gustaría inyectar un poco de configuración en mi método de fábrica, y Jackson permite esto a través del uso de @JacksonInject y una llamada a withInjectableValues(InjectableValues) en el ObjectMapper.

Esto es, finalmente, el tipo de código me gustaría usar:

class MyClass { 
    final MyField[] myFields; 

    public MyClass(MyField... myFields) { 
     this.myFields = myFields; 
    } 

    @JsonCreator 
    static MyClass create(@JacksonInject("conf") Conf conf, Map<String, Object> map) { 
     MyFields[] myFields; 
     // initialize myFields (or any other object) based on the content of map 
     // and also make use of the inject conf 
     return new MyClass(myFields); 
    } 
} 

Desafortunadamente, Jackson lanza el siguiente tipo de excepciones:

  • al intentar el truco en el constructor

JsonMappingException: Argument #1 of constructor [constructor for MyClass, annotations: {[email protected]()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator

  • al intentar el truco en el método de fábrica

JsonMappingException: Argument #1 of factory method [method create, annotations: {[email protected]()}] has no property name annotation; must have when multiple-paramater static method annotated as Creator

¿Alguien sabe cómo podría resolver el problema?

Para resumir los requisitos, necesito:

  • acceso al mapa de nivel superior (no sé los nombres de las propiedades JSON de antelación)
  • para crear un objeto inmutable (lo que no puede utilice @JsonAnySetter)
  • para inyectar algo de conf para el método @JsonCreator constructor o fábrica decorada

que no puedo cambiar el formato de entrada JSON, que se ve así:

{ 
    "key1":"value1", 
    "key2":"value2", 
    "key3":"value3" 
} 

[EDIT]

Este es un problema conocido: http://jira.codehaus.org/browse/JACKSON-711 (no fijado aún)

Respuesta

4

derecho, que le gustaría tanto utilizar "delegar" creador (solo argumento, en el que la entrada JSON primero se vincula) - diferente del creador "basado en propiedades" donde se pasa el conjunto de parámetros nombrados - y valores inyectables. Idealmente, esto debería funcionar, pero creo que podría no funcionar actualmente. Creo que hay un Jira inscrito para esto, por lo que puedes verificarlo (http://jira.codehaus.org/browse/JACKSON).

Solo para asegurarse: ¿está usando la versión 1.9.2? Ha habido algunas correcciones en esto desde 1.9.0; que al menos daría un mejor mensaje de error.

+0

De hecho, acaba de descubrir este boleto: http://jira.codehaus.org/browse/JACKSON-711 – killy971

+0

Ah sí. Asegúrese de votar, como dije, debería funcionar, pero lamentablemente es una de las combinaciones más complicadas de apoyar, solo por los aspectos de la implementación. – StaxMan

Cuestiones relacionadas