Comment construire couramment JSON en Java?


Je pense à quelque chose comme:

String json = new JsonBuilder()
  .add("key1", "value1")
  .add("key2", "value2")
  .add("key3", new JsonBuilder()
    .add("innerKey1", "value3"))
  .toJson();

Quelle bibliothèque Java JSON est la meilleure pour ce type de construction fluide?

Update : J'ai enveloppé GSON et j'ai obtenu presque le résultat souhaité ... avec un attelage.

Author: Community, 2012-01-16

8 answers

J'utilise l'organisation .json library et l'a trouvé agréable et convivial.

Exemple:

String jsonString = new JSONObject()
                  .put("JSON1", "Hello World!")
                  .put("JSON2", "Hello my World!")
                  .put("JSON3", new JSONObject()
                       .put("key1", "value1")).toString();

System.out.println(jsonString);

SORTIE:

{"JSON2":"Hello my World!","JSON3":{"key1":"value1"},"JSON1":"Hello World!"}
 76
Author: dku.rajkumar, 2017-03-22 09:21:14

Voir la spécification Java Json. C'est la bonne façon:

String json = Json.createObjectBuilder()
            .add("key1", "value1")
            .add("key2", "value2")
            .build()
            .toString();
 70
Author: Jumar Polanco, 2016-11-10 18:17:06

J'ai récemment créé une bibliothèque pour créer couramment des objets Gson:

Http://jglue.org/fluent-json/

Cela fonctionne comme ceci:

  JsonObject jsonObject = JsonBuilderFactory.buildObject() //Create a new builder for an object
  .addNull("nullKey")                            //1. Add a null to the object

  .add("stringKey", "Hello")                     //2. Add a string to the object
  .add("stringNullKey", (String) null)           //3. Add a null string to the object

  .add("numberKey", 2)                           //4. Add a number to the object
  .add("numberNullKey", (Float) null)            //5. Add a null number to the object

  .add("booleanKey", true)                       //6. Add a boolean to the object
  .add("booleanNullKey", (Boolean) null)         //7. Add a null boolean to the object

  .add("characterKey", 'c')                      //8. Add a character to the object
  .add("characterNullKey", (Character) null)     //9. Add a null character to the object

  .addObject("objKey")                           //10. Add a nested object
    .add("nestedPropertyKey", 4)                 //11. Add a nested property to the nested object
    .end()                                       //12. End nested object and return to the parent builder

  .addArray("arrayKey")                          //13. Add an array to the object
    .addObject()                                 //14. Add a nested object to the array
      .end()                                     //15. End the nested object
    .add("arrayElement")                         //16. Add a string to the array
    .end()                                       //17. End the array

    .getJson();                                  //Get the JsonObject

String json = jsonObject.toString();

Et par la magie des génériques, il génère des erreurs de compilation si vous essayez d'ajouter un élément à un tableau avec une clé de propriété ou un élément à un objet sans nom de propriété:

JsonObject jsonArray = JsonBuilderFactory.buildArray().addObject().end().add("foo", "bar").getJson(); //Error: tried to add a string with property key to array.
JsonObject jsonObject = JsonBuilderFactory.buildObject().addArray().end().add("foo").getJson(); //Error: tried to add a string without property key to an object.
JsonArray jsonArray = JsonBuilderFactory.buildObject().addArray("foo").getJson(); //Error: tried to assign an object to an array.
JsonObject jsonObject = JsonBuilderFactory.buildArray().addObject().getJson(); //Error: tried to assign an object to an array.

Enfin, il existe un support de mappage dans l'API qui vous permet de mapper vos objets de domaine en JSON. Le but étant quand Java8 est libéré vous pourrez faire quelque chose comme ceci:

Collection<User> users = ...;
JsonArray jsonArray = JsonBuilderFactory.buildArray(users, { u-> buildObject()
                                                                 .add("userName", u.getName())
                                                                 .add("ageInYears", u.getAge()) })
                                                                 .getJson();
 11
Author: Bryn, 2013-04-14 21:57:35

Si vous utilisez Jackson faire beaucoup de JsonNode construire dans le code, vous pouvez être intéressant dans l'ensemble d'utilitaires suivants. L'avantage de les utiliser est qu'ils prennent en charge un style de chaînage plus naturel qui montre mieux la structure du JSON en construction.

Voici un exemple d'utilisation:

import static JsonNodeBuilders.array;
import static JsonNodeBuilders.object;

...

val request = object("x", "1").with("y", array(object("z", "2"))).end();

Qui est équivalent au JSON suivant:

{"x":"1", "y": [{"z": "2"}]}

Voici les classes:

import static lombok.AccessLevel.PRIVATE;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;

/**
 * Convenience {@link JsonNode} builder.
 */
@NoArgsConstructor(access = PRIVATE)
public final class JsonNodeBuilders {

  /**
   * Factory methods for an {@link ObjectNode} builder.
   */

  public static ObjectNodeBuilder object() {
    return object(JsonNodeFactory.instance);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, boolean v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, int v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, float v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, String v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, String v1, @NonNull String k2, String v2) {
    return object(k1, v1).with(k2, v2);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, String v1, @NonNull String k2, String v2,
      @NonNull String k3, String v3) {
    return object(k1, v1, k2, v2).with(k3, v3);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, JsonNodeBuilder<?> builder) {
    return object().with(k1, builder);
  }

  public static ObjectNodeBuilder object(JsonNodeFactory factory) {
    return new ObjectNodeBuilder(factory);
  }

  /**
   * Factory methods for an {@link ArrayNode} builder.
   */

  public static ArrayNodeBuilder array() {
    return array(JsonNodeFactory.instance);
  }

  public static ArrayNodeBuilder array(@NonNull boolean... values) {
    return array().with(values);
  }

  public static ArrayNodeBuilder array(@NonNull int... values) {
    return array().with(values);
  }

  public static ArrayNodeBuilder array(@NonNull String... values) {
    return array().with(values);
  }

  public static ArrayNodeBuilder array(@NonNull JsonNodeBuilder<?>... builders) {
    return array().with(builders);
  }

  public static ArrayNodeBuilder array(JsonNodeFactory factory) {
    return new ArrayNodeBuilder(factory);
  }

  public interface JsonNodeBuilder<T extends JsonNode> {

    /**
     * Construct and return the {@link JsonNode} instance.
     */
    T end();

  }

  @RequiredArgsConstructor
  private static abstract class AbstractNodeBuilder<T extends JsonNode> implements JsonNodeBuilder<T> {

    /**
     * The source of values.
     */
    @NonNull
    protected final JsonNodeFactory factory;

    /**
     * The value under construction.
     */
    @NonNull
    protected final T node;

    /**
     * Returns a valid JSON string, so long as {@code POJONode}s not used.
     */
    @Override
    public String toString() {
      return node.toString();
    }

  }

  public final static class ObjectNodeBuilder extends AbstractNodeBuilder<ObjectNode> {

    private ObjectNodeBuilder(JsonNodeFactory factory) {
      super(factory, factory.objectNode());
    }

    public ObjectNodeBuilder withNull(@NonNull String field) {
      return with(field, factory.nullNode());
    }

    public ObjectNodeBuilder with(@NonNull String field, int value) {
      return with(field, factory.numberNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, float value) {
      return with(field, factory.numberNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, boolean value) {
      return with(field, factory.booleanNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, String value) {
      return with(field, factory.textNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, JsonNode value) {
      node.set(field, value);
      return this;
    }

    public ObjectNodeBuilder with(@NonNull String field, @NonNull JsonNodeBuilder<?> builder) {
      return with(field, builder.end());
    }

    public ObjectNodeBuilder withPOJO(@NonNull String field, @NonNull Object pojo) {
      return with(field, factory.pojoNode(pojo));
    }

    @Override
    public ObjectNode end() {
      return node;
    }

  }

  public final static class ArrayNodeBuilder extends AbstractNodeBuilder<ArrayNode> {

    private ArrayNodeBuilder(JsonNodeFactory factory) {
      super(factory, factory.arrayNode());
    }

    public ArrayNodeBuilder with(boolean value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull boolean... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(int value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull int... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(float value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(String value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull String... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull Iterable<String> values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(JsonNode value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull JsonNode... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(JsonNodeBuilder<?> value) {
      return with(value.end());
    }

    public ArrayNodeBuilder with(@NonNull JsonNodeBuilder<?>... builders) {
      for (val builder : builders)
        with(builder);
      return this;
    }

    @Override
    public ArrayNode end() {
      return node;
    }

  }

}

Notez que l'implémentation utilise Lombok, mais vous pouvez facilement désugar il pour remplir le passe-partout Java.

 4
Author: btiernay, 2016-04-07 16:54:03
String json = new JsonBuilder(new GsonAdapter())
  .object("key1", "value1")
  .object("key2", "value2")
  .object("key3")
    .object("innerKey1", "value3")
    .build().toString();

Si vous pensez que la solution ci-dessus est élégante, veuillez essayer ma bibliothèque JsonBuilder. Il a été créé pour permettre une façon de construire des structures json pour de nombreux types de bibliothèques Json. Les implémentations actuelles incluent Gson, Jackson et MongoDB. Pour ie. Jackson juste échanger:

String json = new JsonBuilder(new JacksonAdapter()).

J'ajouterai volontiers d'autres sur demande, il est également assez facile d'en implémenter un par soi-même.

 2
Author: Homyk, 2015-11-23 14:40:31

Il semble que vous souhaitiez probablement vous procurer json-lib:

Http://json-lib.sourceforge.net/

Douglas Crockford est le gars qui a inventé JSON; sa bibliothèque Java est ici:

Http://www.json.org/java/

On dirait que les gens de json-lib ont repris là où Crockford s'était arrêté. Les deux prennent pleinement en charge JSON, les deux utilisent (compatible, pour autant que je sache) les constructions JSONObject, JSONArray et JSONFunction.

'J'espère que cela aide ..

 1
Author: paulsm4, 2012-01-16 05:34:07

L'implémentation de référence sur json.org comprend une interface fluide. Découvrez JSONWriter et sa sous-classe d'implémentation toString JSONStringer

 0
Author: ykaganovich, 2013-09-03 20:34:50

Il est beaucoup plus facile que vous ne le pensez d'écrire le vôtre, utilisez simplement une interface pour JsonElementInterface avec une méthode string toJson(), et une classe abstraite AbstractJsonElement implémentant cette interface,

Alors tout ce que vous avez à faire est d'avoir une classe pour {[3] } qui implémente l'interface, et JSONValue (tout jeton), JSONArray ([...]), et JSONObject ({...}) qui étendent la classe abstraite

JSONObject a une liste de JSONProperty's
JSONArray a une liste de AbstractJsonElement's

Votre fonction add dans chacun devrait prendre une liste vararg de cela type, et retour this

Maintenant, si vous n'aimez pas quelque chose que vous pouvez simplement ajuster

L'avantage de l'interface et la classe abstraite est que JSONArray ne peut pas accepter des propriétés, mais JSONProperty peut accepter des objets ou des tableaux

 0
Author: Austin_Anderson, 2017-05-30 19:19:30