如何在Java中流畅地构建JSON?

时间:2012-01-16 05:28:50

标签: java json

我想的是:

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

哪种Java JSON库最适合这种流畅的建筑?

更新:我包装了GSON并得到了几乎所需的结果...... with one hitch

11 个答案:

答案 0 :(得分:103)

我正在使用org.json库,发现它很友好。

示例:

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

<强>输出:

{"JSON2":"Hello my World!","JSON3":{"key1":"value1"},"JSON1":"Hello World!"}

答案 1 :(得分:89)

请参阅Java Json specification。 这是正确的方法:

String json = Json.createObjectBuilder()
            .add("key1", "value1")
            .add("key2", "value2")
            .build()
            .toString();

答案 2 :(得分:11)

我最近创建了一个用于流畅创建Gson对象的库:

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

它的工作原理如下:

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

通过泛型的魔力,如果你试图将一个元素添加到一个带有属性键的数组或一个没有属性名的对象的元素,它会产生编译错误:

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.

最后,API中有映射支持,允许您将域对象映射到JSON。 Java8发布的目标是你能够做到这样的事情:

Collection<User> users = ...;
JsonArray jsonArray = JsonBuilderFactory.buildArray(users, { u-> buildObject()
                                                                 .add("userName", u.getName())
                                                                 .add("ageInYears", u.getAge()) })
                                                                 .getJson();

答案 3 :(得分:5)

如果您正在使用Jackson在代码中进行大量2016/04/07 12:39:05.281 2s delayed 2016/04/07 12:39:05.281 构建,那么您可能会对以下一组实用程序感兴趣。使用它们的好处是它们支持更自然的链接样式,更好地显示正在构建的JSON的结构。

以下是一个示例用法:

JsonNode

这相当于以下JSON:

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

...

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

以下是课程:

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

请注意,该实现使用Lombok,但您可以轻松地将其用于填充Java样板。

答案 4 :(得分:2)

String json = new JsonBuilder(new GsonAdapter())
  .object("key1", "value1")
  .object("key2", "value2")
  .object("key3")
    .object("innerKey1", "value3")
    .build().toString();

如果您认为上述解决方案很优雅,请尝试我的JsonBuilder lib。它的创建是为了允许为多种类型的Json库构建json结构的一种方法。目前的实施包括Gson,Jackson和MongoDB。对于ie。杰克逊只是交换:

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

我很乐意根据要求添加其他人,它也很容易自己实现。

答案 5 :(得分:1)

听起来你可能想要获得json-lib:

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

Douglas Crockford是发明JSON的人;他的Java库在这里:

http://www.json.org/java/

听起来像json-lib的人们在Crockford离开的地方捡到了。两者都完全支持JSON,两者都使用(据我所知,兼容)JSONObject,JSONArray和JSONFunction构造。

'希望有所帮助..

答案 6 :(得分:0)

json.org上的参考实现包括一个流畅的界面。查看JSONWriter及其toString实现子类JSONStringer

答案 7 :(得分:0)

它比你想象的要容易得多,只需使用方法JsonElementInterface的{​​{1}}接口和实现该接口的抽象类string toJson()

然后你所要做的就是有一个实现接口的AbstractJsonElement类,JSONProperty(任何标记),JSONValue([...])和{ {1}}({...})扩展抽象类

JSONArray有一个JSONObject的列表 JSONObject有一个JSONProperty

列表

每个中的add函数都应该采用该类型的vararg列表,并返回JSONArray

现在,如果你不喜欢某些东西,你可以调整一下

inteface和抽象类的好处是AbstractJsonElement不能接受属性,但this可以接受对象或数组

答案 8 :(得分:0)

您可以使用一种Java模板引擎。 我喜欢这种方法,因为您将逻辑与视图分开。

Java 8 +:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.9.6</version>
</dependency>

Java 6/7:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.8.18</version>
</dependency>

示例模板文件:

{{#items}}
Name: {{name}}
Price: {{price}}
  {{#features}}
  Feature: {{description}}
  {{/features}}
{{/items}}

可能有一些备用代码:

public class Context {
  List<Item> items() {
    return Arrays.asList(
      new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
      new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
    );
  }

  static class Item {
    Item(String name, String price, List<Feature> features) {
      this.name = name;
      this.price = price;
      this.features = features;
    }
    String name, price;
    List<Feature> features;
  }

  static class Feature {
    Feature(String description) {
       this.description = description;
    }
    String description;
  }
}

这将导致:

Name: Item 1
Price: $19.99
  Feature: New!
  Feature: Awesome!
Name: Item 2
Price: $29.99
  Feature: Old.
  Feature: Ugly.

答案 9 :(得分:0)

Underscore-java 库具有 json 生成器。

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

答案 10 :(得分:0)

我来到这里寻找一种使用流畅的 json 构建器编写其余端点测试的好方法。就我而言,我使用 JSONObject 来构建一个专门的构建器。它需要一些工具,但用法非常好:

import lombok.SneakyThrows;
import org.json.JSONObject;

public class MemberJson extends JSONObject {

    @SneakyThrows
    public static MemberJson builder() {
        return new MemberJson();
    }

    @SneakyThrows
    public MemberJson name(String name) {
        put("name", name);
        return this;
    }

}
MemberJson.builder().name("Member").toString();