没有注释的jackson过滤器属性

时间:2012-06-06 14:37:15

标签: java json annotations jackson

public Class User {
    private String name;
    private Integer age;
    ...
}

ObjectMapper om = new ObjectMapper();
om.writeValueAsString(user);

如何在不使用@JsonIgnore等任何注释的情况下过滤属性?

3 个答案:

答案 0 :(得分:2)

按名称排除属性的示例:

public Class User {
    private String name = "abc";
    private Integer age = 1;
    //getters
}

@JsonFilter("dynamicFilter")
public class DynamicMixIn {
}

User user = new User();
String[] propertiesToExclude = {"age"};
ObjectMapper mapper = new ObjectMapper()
      .addMixIn(Object.class, DynamicMixIn.class);
FilterProvider filterProvider = new SimpleFilterProvider()
                .addFilter("dynamicFilter", SimpleBeanPropertyFilter.serializeAllExcept(propertiesToExclude));
        mapper.setFilterProvider(filterProvider);

mapper.writeValueAsString(user); // {"name":"abc"}

您可以代替DynamicMixIn创建MixInByPropName

@JsonIgnoreProperties(value = {"age"})
public class MixInByPropName {
}

ObjectMapper mapper = new ObjectMapper()
      .addMixIn(Object.class, MixInByPropName.class);

mapper.writeValueAsString(user); // {"name":"abc"}

注意:如果您只想为User排除属性,可以将方法Object.class的参数addMixIn更改为User.class

按类型排除属性,您可以创建MixInByType

@JsonIgnoreType
public class MixInByType {
}

ObjectMapper mapper = new ObjectMapper()
      .addMixIn(Integer.class, MixInByType.class);

mapper.writeValueAsString(user); // {"name":"abc"}

答案 1 :(得分:1)

有点慢,但我使用两相复制。首先使用Spring BeanUtils,然后使用Jackson。

public static void copyWithIgnore(final Object source, final Object target, final String... ignoreProperties) {

    try {
        final ObjectMapper mapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        final Object ignoredSource;

        if (ObjectUtils.isEmpty(ignoreProperties)) {
            ignoredSource = source;
        } else {
            ignoredSource = source.getClass().getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(source, ignoredSource, ignoreProperties);
        }

        mapper.readerForUpdating(target).readValue(mapper.writeValueAsString(ignoredSource));
    } catch (Exception e) {
        throw new RuntimeException("Cannot deserialize and instantiate source class");
    }
}

答案 2 :(得分:0)

我写了一个名为Squiggly Filter的库,它根据Facebook Graph API语法的一个子集选择字段。例如,要选择用户对象的地址字段的zipCode,您将使用查询字符串?fields=address{zipCode}。 Squiggly Filter的一个优点是,只要您可以访问呈现json的ObjectMapper,就不必修改任何控制器方法的代码。

假设您正在使用servlet API(这不是必需的,但可能是最常见的用例),您可以执行以下操作:

1)注册过滤器

<filter> 
    <filter-name>squigglyFilter</filter-name>
    <filter-class>com.github.bohnman.squiggly.web.SquigglyRequestFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>squigglyFilter</filter-name>
    <url-pattern>/**</url-pattern> 
</filter-mapping>

2)初始化ObjectMapper

Squiggly.init(objectMapper, new RequestSquigglyContextProvider());

3)您现在可以过滤您的json

curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2}

有关Squiggly过滤器的更多信息,请参见github