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 genre de bâtiment fluent?

Update : j'ai enveloppé GSON et obtenu presque le résultat désiré ... avec une attache .

60
demandé sur Community 2012-01-16 09:28:50

8 réponses

j'utilise le org.JSON bibliothèque et trouvé pour être agréable et amical.

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
répondu dku.rajkumar 2017-03-22 09:21:14

Voir la Java Json spécification . C'est la bonne voie:

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

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

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

ça marche comme ça:

  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 y a la cartographie prise en charge dans L'API qui vous permet de mapper vos objets de domaine vers JSON. Le but étant que lorsque Java8 sera 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
répondu Bryn 2013-04-14 21:57:35

si vous utilisez Jackson faire beaucoup de JsonNode bâtiment en code, vous pouvez être intéressant dans l'ensemble suivant d'Utilités. L'avantage de les utiliser est qu'ils supportent un style de chaînage plus naturel qui montre mieux la structure du JSON en construction.

voici un exemple d'usage:

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

...

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

qui est l'équivalent du 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 le désactiver pour remplir le boilerplate Java.

4
répondu 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, alors s'il vous plaît essayer mon JsonBuilder lib. 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 comprennent Gson, Jackson et MongoDB. For ie. Jackson il suffit de le remplacer:

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

je vais heureusement ajouter d'autres sur demande, il est aussi assez facile de mettre en œuvre un par soi-même.

2
répondu Homyk 2015-11-23 14:40:31

il semble que vous voulez probablement mettre la main sur 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'est arrêté. Tous les deux supportent entièrement JSON, tous les deux utilisent (compatible, dans la mesure où I can tell) JSONObject, JSONArray et jsonfunction constructs.

'Espère que ça aide ..

1
répondu paulsm4 2012-01-16 05:34:07

la mise en œuvre de référence sur json.org comprend une interface fluide. Check out JSONWriter et sa sous-classe de mise en œuvre toString JSONStringer

0
répondu ykaganovich 2013-09-03 20:34:50

il est beaucoup plus facile que vous pensez pour écrire votre propre, il suffit d'utiliser une interface pour JsonElementInterface avec une méthode string toJson() , et une classe abstraite AbstractJsonElement mise en œuvre de cette interface,

, alors tout ce que vous avez à faire est d'avoir une classe pour JSONProperty qui implémente l'interface, et JSONValue (n'importe quel 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 ce type, et retourner this

maintenant si vous n'aimez pas quelque chose, vous pouvez juste le modifier

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

0
répondu Austin_Anderson 2017-05-30 19:19:30