2011-06-10 21 views
23

我使用Jackson构建自定义JSON对象。这是否正确的方式呢?使用Jackson JsonNodeFactory的最佳方法

它似乎工作正常(和输出是正确的),但我可能会缺少我使用JsonNodeFactory的方式。对象是否像我在这里所做的那样被传递过来?

JsonNodeFactory factory = JsonNodeFactory.instance; 

     ObjectNode dataTable = new ObjectNode(factory); 

     ArrayNode aaData = new ArrayNode(factory); 

     for (PkgLoad pkgLoad : pkgLoadList) { 
      ObjectNode row = new ObjectNode(factory); 
      row.put("ounces", pkgLoad.ounces); 
      row.put("revolutions", pkgLoad.revolutions); 

      aaData.add(row); 
     } 

     dataTable.put("aaData", aaData); 

回答

36

这可以工作,但意图是它是工厂创建实例。但最常见的,你只是获得使用ObjectMapper,像所有的它:

ObjectMapper mapper = new ObjectMapper(); 
ObjectNode dataTable = mapper.createObjectNode(); 
ArrayNode aa = dataTable.putArray("aaData"); 

单独JsonNodeFactory的主要原因是允许你创建自定义节点类型(标准情况下的通常的子类);然后将ObjectMapper配置为使用不同的工厂。 为方便起见,ArrayNode和ObjectNode确实引用了一个工厂实例,该实例与“putArray”和其他需要创建新节点的方法一起使用。

3

只是一个建议,会更容易直接处理简单的数据类型和序列化那些JSON和背部使用杰克逊ObjectMapper,而不是处理原始Jackson Treemodel

所以,在你的榜样,您可以创建以下类型的结构:

class AaData{ 
    private List<ARow> rowList = new ArrayList<ARow>(); 
.. 

class ARow{ 
    String ounces; 
    String revolutions; 
.. 

那么下面会产生相应的JSON为您提供:

StringWriter sw = new StringWriter(); 
JsonFactory jf = new JsonFactory(); 
ObjectMapper m = new ObjectMapper(); 
m.writeValue(sw, aaData); 
System.out.println(sw.toString()); 
+0

这会更好,我在某些情况下做到了。问题是,在这种情况下,我需要控制每一行,因为我有关于写什么的条件语句。有时盎司是克。我必须在每一行上写行颜色。每行都不相同。 – 2011-06-11 15:30:59

+0

@德鲁H,我见过你几次发布这个项目。总体而言,在我看来,如果在反序列化时对对象模型进行的更改或基于演示文稿的更改较少或者没有进行基于演示文稿的更改,并且仅根据存在于JSON在不注入额外数据的情况下,随后在项目中靠近要显示数据的位置放置代码,该代码与生成视图模型(或更改现有模型)有关。 – 2011-06-12 03:33:00

+1

(继续...)我的观点是,如果可以简化JSON和Java数据结构之间的数据绑定,那么保持简单。当反序列化只需要两到三行代码时,这非常棒,当使用Gson或Jackson这样的API时,完全可能且非常常见。对我而言,这是使用这些API的主要原因。 – 2011-06-12 03:36:00

2

如果你在代码中做了很多JsonNode构建,你可能会对以下一组实用程序感兴趣。使用它们的好处是,它们支持更自然的链式风格,可以更好地展示构建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样板。

0
ObjectNode factory = JsonNodeFactory.instance.objectNode(); 

这很好。我认为这是一个更简单的方法。