Je souhaite pouvoir accéder aux propriétés d'une chaîne JSON dans ma méthode d'action Java. La chaîne est disponible en disant simplement myJsonString = object.getJson()
. Voici un exemple de ce à quoi la chaîne peut ressembler:
{
'title': 'ComputingandInformationsystems',
'id': 1,
'children': 'true',
'groups': [{
'title': 'LeveloneCIS',
'id': 2,
'children': 'true',
'groups': [{
'title': 'IntroToComputingandInternet',
'id': 3,
'children': 'false',
'groups': []
}]
}]
}
Dans cette chaîne, chaque objet JSON contient un tableau d'autres objets JSON. L'intention est d'extraire une liste d'ID où n'importe quel objet possédant une propriété de groupe contenant d'autres objets JSON. J'ai regardé Gson de Google comme un plugin JSON potentiel. Quelqu'un peut-il offrir des conseils sur la manière de générer Java à partir de cette chaîne JSON?
J'ai regardé le Gson de Google comme un plugin JSON potentiel. Quelqu'un peut-il offrir des conseils sur la manière de générer Java à partir de cette chaîne JSON?
Google Gson prend en charge les génériques et les haricots imbriqués. Le []
de JSON représente un tableau et doit être mappé sur une collection Java telle que List
ou simplement sur un tableau Java. Le {}
dans JSON représente un objet et doit être mappé sur un Java Map
ou seulement une classe JavaBean.
Vous avez un objet JSON avec plusieurs propriétés dont la propriété groups
représente un tableau d'objets imbriqués du même type. Cela peut être analysé avec Gson de la manière suivante:
package com.stackoverflow.q1688099;
import Java.util.List;
import com.google.gson.Gson;
public class Test {
public static void main(String... args) throws Exception {
String json =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";
// Now do the magic.
Data data = new Gson().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String title;
private Long id;
private Boolean children;
private List<Data> groups;
public String getTitle() { return title; }
public Long getId() { return id; }
public Boolean getChildren() { return children; }
public List<Data> getGroups() { return groups; }
public void setTitle(String title) { this.title = title; }
public void setId(Long id) { this.id = id; }
public void setChildren(Boolean children) { this.children = children; }
public void setGroups(List<Data> groups) { this.groups = groups; }
public String toString() {
return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
}
}
Assez simple, n'est-ce pas? Ayez juste un JavaBean approprié et appelez Gson#fromJson()
.
Bewaaaaare de Gson! C'est très cool, très bien, mais dès que vous voulez faire autre chose que de simples objets, vous pouvez facilement avoir besoin de commencer à construire votre propre sérialiseur (ce qui n'est pas celui difficile).
De plus, si vous avez un tableau d'objets et que vous désérialisez un json dans ce tableau d'objets, les vrais types sont LOST! Les objets complets ne seront même pas copiés! Utilisez XStream .. Ce qui, si vous utilisez jsondriver et définissez les paramètres appropriés, encodera les types laids dans le JSON réel, de sorte que vous ne perdiez rien. Un petit prix à payer (laid JSON) pour une sérialisation réelle.
Notez que Jackson résout ces problèmes et est plus rapide que GSON.
Bizarrement, le seul processeur JSON décent mentionné à ce jour est GSON.
Voici plus de bons choix:
EDIT (août/2013):
Un plus à considérer:
Ou avec Jackson:
String json = "...
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});
Si, par quelque changement que ce soit, vous vous trouvez dans une application qui utilise déjà http://restfb.com/ , vous pouvez alors:
import com.restfb.json.JsonObject;
...
JsonObject json = new JsonObject(jsonString);
json.get("title");
etc.
Si vous utilisez n'importe quel type de carte spéciale avec des clés ou des valeurs, vous constaterez que cela n'est pas envisagé par la mise en œuvre de Google.
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
String key = (String) itr.next();
keyArrayList.put(key, yourJson.get(key).toString());
}
JSONObject
en Java Object
Employee.Java
import Java.util.HashMap;
import Java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
"id",
"firstName",
"lastName"
})
public class Employee {
@JsonProperty("id")
private Integer id;
@JsonProperty("firstName")
private String firstName;
@JsonProperty("lastName")
private String lastName;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* @return
* The id
*/
@JsonProperty("id")
public Integer getId() {
return id;
}
/**
*
* @param id
* The id
*/
@JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}
/**
*
* @return
* The firstName
*/
@JsonProperty("firstName")
public String getFirstName() {
return firstName;
}
/**
*
* @param firstName
* The firstName
*/
@JsonProperty("firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
*
* @return
* The lastName
*/
@JsonProperty("lastName")
public String getLastName() {
return lastName;
}
/**
*
* @param lastName
* The lastName
*/
@JsonProperty("lastName")
public void setLastName(String lastName) {
this.lastName = lastName;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
LoadFromJSON.Java
import org.codehaus.jettison.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
public class LoadFromJSON {
public static void main(String args[]) throws Exception {
JSONObject json = new JSONObject();
json.put("id", 2);
json.put("firstName", "hello");
json.put("lastName", "world");
byte[] jsonData = json.toString().getBytes();
ObjectMapper mapper = new ObjectMapper();
Employee employee = mapper.readValue(jsonData, Employee.class);
System.out.print(employee.getLastName());
}
}
Quel est le problème avec les choses standard?
JSONObject jsonObject = new JSONObject(someJsonString);
JSONArray jsonArray = jsonObject.getJSONArray("someJsonArray");
String value = jsonArray.optJSONObject(i).getString("someJsonValue");
Faites un essai:
https://github.com/RichardHightower/boon
C'est méchant vite:
https://github.com/RichardHightower/json-parsers-benchmark
Ne prenez pas ma parole pour cela ... consultez le point de repère Gatling.
https://github.com/gatling/json-parsers-benchmark
(Jusqu'à 4 fois dans certains cas, et sur des centaines de tests. Il dispose également d'un mode de superposition d'index encore plus rapide. Il est jeune mais compte déjà certains utilisateurs.)
Il peut analyser JSON avec les cartes et les listes plus rapidement que n'importe quelle autre bibliothèque peut analyser un DOM JSON sans mode de superposition d'index. Avec le mode Boon Index Overlay, c'est encore plus rapide.
Il possède également un mode très rapide JSON lax et un mode analyseur PLIST. :) (et a une mémoire très faible, en mode direct d'octets avec encodage UTF-8 à la volée).
Il dispose également du mode JSON au JavaBean le plus rapide.
C'est nouveau, mais si vous recherchez une API simple et rapide, je ne pense pas qu'il existe une API plus rapide ou plus minimaliste.
En fonction du format JSON d'entrée (chaîne/fichier), créez un jSONString. Un exemple d'objet de classe Message correspondant à JSON peut être obtenu comme suit:
Message msgFromJSON = new ObjectMapper (). ReadValue (jSONString, Message.class);
Le moyen le plus simple consiste à utiliser cette méthode softconvertvalue, qui est une méthode personnalisée dans laquelle vous pouvez convertir jsonData en votre classe Dto spécifique.
Dto response = softConvertValue(jsonData, Dto.class);
public static <T> T softConvertValue(Object fromValue, Class<T> toValueType)
{
ObjectMapper objMapper = new ObjectMapper();
return objMapper
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.convertValue(fromValue, toValueType);
}