web-dev-qa-db-fra.com

Conversion de données JSON en objet Java

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?

245
Faiyet

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() .

Voir également:

317
BalusC

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.

43
Jor

Bizarrement, le seul processeur JSON décent mentionné à ce jour est GSON.

Voici plus de bons choix:

  • Jackson ( Github ) - Liaison de données puissante (JSON vers/depuis des POJO), diffusion en continu (ultra rapide), modèle d'arborescence (pratique pour un accès sans type)
  • Flex-JSON - sérialisation hautement configurable

EDIT (août/2013):

Un plus à considérer:

  • Genson - fonctionnalité similaire à celle de Jackson, conçue pour être plus facile à configurer par le développeur
25
StaxMan

Ou avec Jackson:

String json = "...
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});
14
Gene De Lisa

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.

6
cherouvim

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.

3
Juanma
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
    String key = (String) itr.next();
    keyArrayList.put(key, yourJson.get(key).toString());
}
3
HEAT

Facile et fonctionnel Java code pour convertir 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());

    }
}
3
Rahul Raina

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");
2
Kevin

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.

0
RickHigh

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);

0
Shailendra Singh

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);
}
0
Dipen Chawla