【问题标题】:jackson filter properties without annotations没有注释的杰克逊过滤器属性
【发布时间】:2012-06-06 14:37:15
【问题描述】:
public Class User {
    private String name;
    private Integer age;
    ...
}

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

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

【问题讨论】:

    标签: java json annotations jackson


    【解决方案1】:

    使用 Jackson 有两种可能的方式

    混合注释:- http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html

    JSON 过滤器:- http://wiki.fasterxml.com/JacksonFeatureJsonFilter

    【讨论】:

      【解决方案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 的属性,您可以将方法 addMixIn 的参数 Object.class 更改为 User.class

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

      @JsonIgnoreType
      public class MixInByType {
      }
      
      ObjectMapper mapper = new ObjectMapper()
            .addMixIn(Integer.class, MixInByType.class);
      
      mapper.writeValueAsString(user); // {"name":"abc"}
      

      【讨论】:

        【解决方案3】:

        有点慢,但我使用两阶段复制。首先使用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");
            }
        }
        

        【讨论】:

          【解决方案4】:

          我编写了一个名为 Squiggly Filter 的库,它根据 Facebook Graph API 语法的子集选择字段。例如,要选择用户对象的地址字段的邮政编码,您可以使用查询字符串?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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-12
            • 2015-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多