使用JacksonJson动态忽略属性

时间:2011-08-12 09:23:23

标签: json spring jackson

我知道有多种方法可以告诉JacksonJson忽略它 渲染过程中的属性,但它们都是静态的。 (JasonIgnore,MixIn类,..)。

这是我的情景。域对象可以实现名为FilteredDomain的接口 允许它被动态过滤。界面很简单,只暴露一种方法 “getIgnoreProperties”。 (要忽略的属性列表)。

然后我注册了一个绑定到FilteredDomain对象的自定义序列化程序。该 代码看起来像:

private class FilteredDomainSerializer extends JsonSerializer<FilteredDomain> {

    public void serialize(FilteredDomain arg, JsonGenerator jgen,
            SerializerProvider provder) throws IOException,
            JsonProcessingException {

        final BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(arg);

        for (PropertyDescriptor pd : wrapper.getPropertyDescriptors()) {
            final String name = pd.getName();

            if (arg.getIgnoreProperties().containsKey(name))
                continue;

            final Object value = wrapper.getPropertyValue(name);

            jgen.writeObjectField(name, value);
        }
    }
}

首先,我真的不喜欢我需要使用Spring Bean包装器获取所有属性的列表并迭代它们(必须有一种方法可以做到这一点是杰克逊json)。

其次,代码仍然不起作用。我收到错误:

org.codehaus.jackson.JsonGenerationException:无法写入字段名称,期望值     在org.codehaus.jackson.impl.JsonGeneratorBase._reportError(JsonGeneratorBase.java:480)     at org.codehaus.jackson.impl.Utf8Generator.writeFieldName(Utf8Generator.java:270)     在org.codehaus.jackson.JsonGenerator.writeObjectField(JsonGenerator.java:1088)     at com.rootmusic.util.SystemJsonObjectMapper $ ValueObjectSerializer.serialize(SystemJsonObjectMapper.java:65)     at com.rootmusic.util.SystemJsonObjectMapper $ ValueObjectSerializer.serialize(SystemJsonObjectMapper.java:1)     at org.codehaus.jackson.map.ser.ContainerSerializers $ IndexedListSerializer.serializeContents(ContainerSerializers.java:304)     at org.codehaus.jackson.map.ser.ContainerSerializers $ IndexedListSerializer.serializeContents(ContainerSerializers.java:254)     at org.codehaus.jackson.map.ser.ContainerSerializers $ AsArraySerializer.serialize(ContainerSerializers.java:142)     在org.codehaus.jackson.map.ser.MapSerializer.serializeFields(MapSerializer.java:287)     在org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:212)     at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:23)     在org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:606)     在org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:280)

1 个答案:

答案 0 :(得分:8)

错误来自于您没有围绕字段名称/值对编写START_OBJECT / END_OBJECT,因此应该很容易修复。

对于更动态的过滤,您可以阅读包含标准方法的this blog entry。如果您有静态定义集(其中一个可以基于每个序列化动态选择),则@JsonView有效,但如果您想要更多动态系统,@ JsonFilter是可行的方法。

或者,另一种相对简单的方法是首先将您的POJO“转换”为地图:

Map props = objectMapper.convertValue(pojo,Map.class);

(类似于将其序列化为JSON,除了结果是一个将呈现为JSON的Map)

然后选择性地修剪Map,并将其序列化为JSON。或者,如果您愿意,可以使用JsonNode(“树模型”)作为修改然后序列化的中间事物。