2014-06-17 9 views
0

j'ai utilisé pour analyser correctement le fichier .json suivant:Comment analyser les tableaux imbriqués avec Jackson?

[ 
    { 
     "latitude": 49.419459253939316, 
     "longitude": 8.676411621072491 
    }, 
    { 
     "latitude": 49.41946061080915, 
     "longitude": 8.676411644939083 
    }, 
    { 
     "latitude": 49.420365910782735, 
     "longitude": 8.676438042403413 
    } 
] 

Le Jackson script suivant renvoie un List de points.

private static <T> List<T> parseFile(final String fileName, 
            Class<T> contentType) { 
    // ... 
    InputStream inputStream = // Open file 
    ObjectMapper objectMapper = new ObjectMapper(); 
    try { 
     TypeFactory typeFactory = objectMapper.getTypeFactory(); 
     CollectionType collectionType = typeFactory 
      .constructCollectionType(List.class, contentType); 
     return objectMapper.readValue(inputStream, collectionType); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

Maintenant, l'ensemble de données devient plus compliqué. Le List de points devient un List de List de points. Je l'ai structuré de cette façon - s'il vous plaît corrigez-moi si ce n'est pas correct.

[ 
    [ 
     { 
      "latitude": 49.419459253939316, 
      "longitude": 8.676411621072491 
     }, 
     { 
      "latitude": 49.41946061080915, 
      "longitude": 8.676411644939083 
     }, 
     { 
      "latitude": 49.420365910782735, 
      "longitude": 8.676438042403413 
     } 
    ], 
    [ 
     { 
      "latitude": 49.40460334213399, 
      "longitude": 8.670034018853409 
     }, 
     { 
      "latitude": 49.404608057285145, 
      "longitude": 8.670028775634165 
     }, 
     { 
      "latitude": 49.40506145685422, 
      "longitude": 8.66955817506422 
     } 
    ] 
] 

Je prépare les POJO suivantes pour stocker les données dans:

public class GeoPoint { 
    public double latitude; 
    public double longitude; 
} 

...

public class ThreePoints { 
    public List<GeoPoint> points; 
} 

Comment dois-je changer ci-dessus analyseur Jackson pour qu'il puisse gérer la tableaux imbriqués? Est-ce que Jackson peut analyser les données dans une structure de classe imbriquée telle que ThreePoints.class?

Répondre

1

Vous pouvez écrire un désérialiseur personnalisé simple

désérialiser à votre classe:

public class GeoPoint { 
    public double latitude; 
    public double longitude; 
} 

public class ThreePoints { 
    public List<GeoPoint> points; 
} 

Ecrire un désérialiseur personnalisé:

class ThreePointsDeserializer extends StdDeserializer<ThreePoints> { 

    protected ThreePointsDeserializer() { 
     super(ThreePoints.class); 
    } 


    @Override 
    public ThreePoints deserialize(JsonParser parser, DeserializationContext ctx) 
      throws IOException, JsonProcessingException { 
     ThreePoints result = new ThreePoints(); 
     GeoPoint[] points = parser.getCodec().readValue(parser, GeoPoint[].class); 
     result.points = Arrays.asList(points); 
     return result; 
    } 
} 

à utiliser qui désérialiseur:

SimpleModule module = new SimpleModule(); 
module.addDeserializer(ThreePoints.class, new ThreePointsDeserializer()); 

ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(module); 

TypeFactory tf = mapper.getTypeFactory(); 
CollectionType collectionType = tf.constructCollectionType(List.class, ThreePoints.class); 

List<ThreePoints> result = mapper.readValue(YOUR_DATA, collectionType); 
2

Vous pouvez simplement créer un type de collection supplémentaire. Voir ci-dessous le code:

TypeFactory typeFactory = mapper.getTypeFactory(); 
CollectionType listType = typeFactory.constructCollectionType(List.class, contentType); 
CollectionType listListType = typeFactory.constructCollectionType(List.class, listType); 
List<List<GeoPoint>> readValue = mapper.readValue(json, rootCollectionType); 
// convert to ThreePoints 

EDIT
Malheureusement, vous n'êtes pas en mesure de dire Jackson de convertir vos JSON à vos POJO cours parce qu'ils ne correspondent pas à l'autre. Jackson ne contient pas non plus d'annotations que vous pouvez utiliser pour mapper votre JSON à vos classes POJO. Tu dois le faire manuellement. En utilisant mon code, vous pouvez écrire un désérialiseur personnalisé pour la classe ThreePoints dans laquelle vous pouvez utiliser le code interne ObjectMapper et mon code ci-dessus. Je pense que vous pourrez facilement convertir List<List<GeoPoint>> readValue en classe ThreePoints. Une autre option - vous pouvez écrire une simple fonction dans votre classe JsonUtil. Si vous ne pouvez vraiment pas changer cela JSON vous devez le faire manuellement.

+0

Pouvez-vous p bail mettre à jour votre solution pour montrer comment je peux produire une 'Liste '? – JJD

0

vous devez lire les valeurs comme Matrix, vous devez d'abord cartographier les valeurs en utilisant un POJO appelé Place.

public class Place { 

    double latitude; 
    double longitude; 

    public double getLatitude() { 
     return latitude; 
    } 

    public void setLatitude(double latitude) { 
     this.latitude = latitude; 
    } 

    public double getLongitude() { 
     return longitude; 
    } 

    public void setLongitude(double longitude) { 
     this.longitude = longitude; 
    } 
}  

Deuxième étape, vous devez mapper le JsonNode dans une matrice.

import java.io.IOException; 
import java.util.List; 
import org.codehaus.jackson.JsonNode; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.codehaus.jackson.map.type.CollectionType; 
import org.codehaus.jackson.map.type.TypeFactory; 


public class Main { 
    static String jsonString = "[" + 
" [" + 
"  {" + 
"   \"latitude\": 49.419459253939316," + 
"   \"longitude\": 8.676411621072491" + 
"  }," + 
"  {" + 
"   \"latitude\": 49.41946061080915," + 
"   \"longitude\": 8.676411644939083" + 
"  }," + 
"  {" + 
"   \"latitude\": 49.420365910782735," + 
"   \"longitude\": 8.676438042403413" + 
"  }" + 
" ]," + 
" [" + 
"  {" + 
"   \"latitude\": 49.40460334213399," + 
"   \"longitude\": 8.670034018853409" + 
"  }," + 
"  {" + 
"   \"latitude\": 49.404608057285145," + 
"   \"longitude\": 8.670028775634165" + 
"  }," + 
"  {" + 
"   \"latitude\": 49.40506145685422," + 
"   \"longitude\": 8.66955817506422" + 
"  }" + 
" ]" + 
"]"; 

    public static void main(String...args) { 
     final ObjectMapper om = new ObjectMapper(); 
     try { 
      final Place[][] dtos = om.readValue(new ObjectMapper() 
       .readValue(jsonString, JsonNode.class), Place[][].class); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Cheers.

+0

Je voudrais l'avoir analysé dans une liste. – JJD

Questions connexes