如何在Java中stream利地构buildJSON?

我在想像这样的事情:

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

哪种Java JSON库最适合这种stream畅的build筑?

更新 :我包装了GSON,并得到了几乎所需的结果… 一个顺利 。

我正在使用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); 

OUTPUT:

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

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

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

我最近创build了一个stream利地创buildGson对象的库:

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

通过generics的魔力,如果您尝试使用属性键或元素将数组添加到没有属性名称的对象,则会生成编译错误:

 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(); 
 String json = new JsonBuilder(new GsonAdapter()) .object("key1", "value1") .object("key2", "value2") .object("key3") .object("innerKey1", "value3") .build().toString(); 

如果你认为上面的解决scheme是优雅的,那么请试试我的JsonBuilder库。 它被创build为允许为许多types的Json库构buildjson结构的一种方式。 目前的实现包括Gson,Jackson和MongoDB。 即, jackson只是交换:

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

我会很高兴地根据要求添加他人,也很容易实现一个人。

这听起来像你可能想要得到json-lib:

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

道格拉斯·克罗克福德是发明JSON的人; 他的Java库在这里:

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

这听起来就像是在克里克福德离开的地方,json-lib中的人们拾起了。 两者都完全支持JSON,都使用(兼容,据我所知)JSONObject,JSONArray和JSONFunction结构。

“希望帮助..

如果你使用的是Jackson, JsonNode在代码中做很多JsonNode构build,你可能会在下面这组实用程序中感兴趣。 使用它们的好处是,它们支持更自然的链式风格,更好地展示正在build设中的JSON的结构。

以下是一个示例用法:

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

这相当于下面的JSON:

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

这里是类:

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

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

json.org上的参考实现包含stream畅的界面。 查看JSONWriter及其toString实现子类JSONStringer

比编写自己的代码容易得多,只需使用一个带有方法string toJson()接口和一个实现该接口的抽象类AbstractJsonElement

那么你所要做的就是拥有一个实现接口的JSONProperty类,以及扩展抽象类的JSONValue (任何标记), JSONArray ([…])和JSONObject ({…}

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

你的每个add函数都应该有一个这个types的variables列表,并返回this

现在,如果你不喜欢的东西,你可以调整它

接口和抽象类的JSONPropertyJSONArray不能接受属性,但JSONProperty可以接受对象或数组