Pregunta

Estoy tratando de analizar una estructura JSON similar a ésta:

    {
 "cars": {
  "112": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "1998"
  },
  "642": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "1990"
  },
  "9242": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "2001"
  }
 }}

Tengo una clase definida con CarEntity makeName, modelo, año atributos definidos y accesibles a través de setters / captadores.

Estoy tratando de deserializar este JSON como esto:

    Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String, CarEntity>>()
   .use("cars.values", Map.class)
   .deserialize(json);

y no funciona :( No deserializar, pero no en Map<String, CarEntity> sino más bien en una profunda mapa (algo así como Map<String, Map<String, Map<String, String>>>)

¿Qué estoy haciendo mal?

¿Fue útil?

Solución

Esta es su problema JSON tiene dos mapas. Uno que contiene la clave 'coches', y uno que contiene la CarEntity real. Por desgracia, no se puede hacer referencia a una sola tecla en un mapa y los tipos de asignar simplemente esa clave en este momento. establecer Generalmente tipos en los valores para colecciones se refiere a todos los valores dentro de la colección. No es necesario especificar los tipos para el primer mapa que contiene la clave "coches" ya que deserializar por defecto.

Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String,Map<String, CarEntity>>>()
    .use("values.values", CarEntity.class )
    .deserialize(json).get("cars");

Los 'values.values' Ruta refiere a los valores de Mapa exteriores entonces atravesar los próximos valores de mapa son todas las instancias CarEntity.

He pensado en cambiar las expresiones de ruta a ser más expresiva que le permite dirigirse a un solo valor en una colección, pero esto aumenta por encima de evaluación de las mismas y de ser compatible con versiones anteriores es un reto.

Otros consejos

Lo más probable es ser mordido por Java Tipo Erasure: biblioteca JSON en cuestión no sabe que usted quiere escribir; todo lo que se ve es el equivalente de Mapa. Por lo que debe especificar al menos el tipo de valor de alguna manera. Con suerte Flexjson puntos documentación cómo.

Alternativamente, usted puede ser capaz de HashMap sub-clase en su propio tipo (MyEntityMap extiende HashMap), ya continuación, escriba la información se puede deducir de tipo súper genérica; y MyEntityMap.class que pasan darían información de tipo que la mayoría de bibliotecas JSON pueden utilizar (Jackson y GSON al menos).

Si estos no funcionan, bibliotecas Jackson y GSON pueden manejar este caso de uso fácil; ambos tienen métodos para especificar los tipos genéricos de deserialización.

Sólo tiene que añadir una llamada más a get("cars") como:

Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String, CarEntity>>()
   .use("cars.values", Map.class)
   .deserialize(json).get("cars");

cadena JSON probablemente fue serializado desde un cars variable de tipo Map<String, CarEntity>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top