Je veux analyser le JSON ci-dessous dans POJO. J'utilise Jackson pour analyser le JSON.
{
"totalSize": 4,
"done": true,
"records": [
{
"attributes": {
"type": "oppor",
"url": "/service/oppor/456"
},
"AccountId": "123",
"Id": "456",
"ProposalID": "103"
}
]
}
Dans le JSON ci-dessus, les champs "totalSize", "done", "records" et "attributs" sont des champs connus. Considérant que "AccountId", "Id" et "PropositionID" sont des champs inconnus. Et dans le JSON ci-dessus, je n'ai pas besoin "d'attributs" pour faire partie de mon objet bean.
Et voici la classe de haricot équivalente pour mon JSON
public class Result {
private int totalSize;
private boolean done;
private List<Map<String, String>> records;
public int getTotalSize() {
return totalSize;
}
public void setTotalSize(int totalSize) {
this.totalSize = totalSize;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
public List<Map<String,String>> getRecords() {
return records;
}
public void setRecords(List<Map<String, String>> records) {
this.records = records;
}
}
Il existe donc des champs inconnus dans l'élément records que je viens d'utiliser List pour obtenir l'élément results dans le bean. Ici dans cette carte, je ne veux pas le champ "attributs". Comment puis-je ignorer cela lors de l'analyse? Et ci-dessous est l'exception que je reçois comme attributs n'est pas un élément de chaîne.
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of Java.lang.String out of START_OBJECT token
at [Source: [B@66fdec9; line: 1, column: 40] (through reference chain: com.sample.json.Result["records"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.Java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.Java:691)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.Java:46)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.Java:11)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringMap(MapDeserializer.Java:430)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.Java:312)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.Java:26)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.Java:227)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.Java:204)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.Java:23)
UPDATE 2015/08/29:
Comme vous l'avez dit
J'ai obtenu un support dynamique sur le terrain en analysant le JSON dans la carte. Ignorer les mauvais éléments JSON est ce qui est en attente
Je suggère que vous devriez traiter JSONObject original pour supprimer l'élément "attributes"
de celui-ci.
JSONObject d'origine, par exemple:
{
"totalSize": 4,
"done": true,
"records": [
{
"attributes": {
"type": "oppor",
"url": "/service/oppor/456"
},
"AccountId": "123",
"Id": "456",
"ProposalID": "103"
}
]
}
Après le processus, le nouveau JSONObject ressemblera à ceci:
{
"records": {
"AccountId": "123",
"Id": "456",
"ProposalID": "103"
},
"totalSize": 4,
"done": true
}
Utilisez le code comme suit:
JSONObject jsonObject;
try {
jsonObject = new JSONObject(jsonString1);
JSONArray jsonArray = new JSONArray(jsonObject.get("records").toString());
JSONObject jsonObject1 = jsonArray.getJSONObject(0);
jsonObject1.remove("attributes");
jsonObject.put("records", jsonObject1);
} catch (JSONException e) {
e.printStackTrace();
}
Ensuite, utilisez votre propre code qui achieved dynamic field support by parsing the JSON into map
.
FIN DE MISE À JOUR 2015/08/29
Je suggère que vous utilisiez Gson
et transient
dans ce cas
Comme ça
String jsonString1 = "{\n" +
" \"totalSize\": 4,\n" +
" \"done\": true,\n" +
" \"records\": [\n" +
" {\n" +
" \"attributes\": {\n" +
" \"type\": \"oppor\",\n" +
" \"url\": \"/service/oppor/456\"\n" +
" },\n" +
" \"AccountId\": \"123\",\n" +
" \"Id\": \"456\",\n" +
" \"ProposalID\": \"103\"\n" +
" }\n" +
" ]\n" +
"}";
Gson gson = new Gson();
Result result1 = gson.fromJson(jsonString1, Result.class);
Vos cours, faites attention à transient
:
public class Result {
private int totalSize;
private boolean done;
private List<Record> records;
}
public class Record {
private transient Map<String, String> attributes;
private int AccountId;
private int Id;
private int ProposalID;
}
Vous obtiendrez le résultat:
P/S: J'ai testé dans Android Studio :)
UPDATE:
String jsonString1 = "{\n" +
" \"totalSize\": 4,\n" +
" \"done\": true,\n" +
" \"records\": [\n" +
" {\n" +
" \"attributes\": {\n" +
" \"type\": \"oppor\",\n" +
" \"url\": \"/service/oppor/456\"\n" +
" },\n" +
" \"AccountId\": \"123\",\n" +
" \"Id\": \"456\",\n" +
" \"ProposalID\": \"103\"\n" +
" }\n" +
" ]\n" +
"}";
Gson gson = new Gson();
Object object = gson.fromJson(jsonString1, Object.class);
Map<String, String> stringMap = (Map<String, String>) object;
Result myResult = new Result();
Iterator entries = stringMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
String key = entry.getKey().toString();
String value = entry.getValue().toString();
switch (key) {
case "totalSize":
myResult.totalSize = (int) Double.parseDouble(entry.getValue().toString());
break;
case "done":
myResult.done = Boolean.valueOf(entry.getValue().toString());
break;
case "records":
try{
Object object1 = entry.getValue();
List<Object> objectList = (List<Object>) object1;
Map<String, Object> stringMap2 = (Map<String, Object>) objectList.get(0);
Map<String, String> recordMap = new HashMap<>();
Iterator entries2 = stringMap2.entrySet().iterator();
while (entries2.hasNext()) {
Map.Entry entry2 = (Map.Entry) entries2.next();
String key2 = entry2.getKey().toString();
String value2 = entry2.getValue().toString();
if (!"attributes".equals(key2)) {
recordMap.put(key2, value2);
}
entries2.remove();
}
myResult.records = recordMap;
} catch (Exception e) {
e.printStackTrace();
}
break;
}
entries.remove();
}
Classes:
public class Result {
private int totalSize;
private boolean done;
private Map<String, String> records;
}
Résultat de débogage:
1) Créer un objet de classe Record
2) Ajoutez @JsonIgnore Annotation sur les champs que vous ne voudrez pas
public class Result {
private int totalSize;
private boolean done;
private Record records;
[..]
}
public class Record {
@JsonIgnore
private Map<String, String> attributes;
private int accountID;
private int id;
private int approvalID;
[..]
}
Je suggère d'utiliser l'annotation @Expose de [Google gson API] [1]. (si cela est autorisé dans votre environnement).
Vous pouvez simplement annoter les champs (avec @Expose
) qui sont obligatoires dans votre fichier json généré et laisser les autres champs. Et lors de la génération de JSON, utilisez la méthode API, excludeFieldsWithoutExposeAnnotation
.
Vous pouvez voir un exemple d'exemple ici .
Note : Dans votre exemple, traitez votre Result
comme un POJO principal et records
est un autre POJO comportant des champs attributes
, accountId
, etc. Ensuite, il y a une relation ( composition Java ) entre eux.
Et après cela, vous pouvez invoquer la conversion de Json en pojo comme ci-dessous--
com.google.gson.Gson gson = new com.google.gson.GsonBuilder()
.excludeFieldsWithoutExposeAnnotation().create();
Result result= gson.fromJson(yourjsonString, Result.class);
Créer une nouvelle classe POJO pour les attributs,
public class Result {
private int totalSize;
private boolean done;
private List<Attributes> records;
// Your Getters & Setters
}
public class Attributes{
List<Map<String,String>> attributes;
// Add other variables if necessary like AccountId, etc.,
// Your Getters & Setters
}