如何排除Jackson不使用注释的字段?

Rom*_*man 35 json jackson

我需要在渲染之前按名称排除某些字段.字段列表是动态的,因此我无法使用注释.

我试图创建自定义序列化程序,但我不能在那里获得字段名称.

在我使用的GSON中ExclusionStrategy,但杰克逊没有这样的功能.有同等的吗?

Pro*_*uce 35

以下按名称排除字段的示例来自我的博客文章,Gson v Jackson - 第4部分.(搜索PropertyFilterMixIn.)此示例演示如何使用FilterProvidera SimpleBeanPropertyFilterserializeAllExcept用户指定的字段名称列表.

@JsonFilter("filter properties by name")  
class PropertyFilterMixIn {}  

class Bar  
{  
  public String id = "42";  
  public String name = "Fred";  
  public String color = "blue";  
  public Foo foo = new Foo();  
}  

class Foo  
{  
  public String id = "99";  
  public String size = "big";  
  public String height = "tall";  
}  

public class JacksonFoo  
{  
  public static void main(String[] args) throws Exception  
  {  
    ObjectMapper mapper = new ObjectMapper();  
    mapper.getSerializationConfig().addMixInAnnotations(  
        Object.class, PropertyFilterMixIn.class);  

    String[] ignorableFieldNames = { "id", "color" };  
    FilterProvider filters = new SimpleFilterProvider()  
      .addFilter("filter properties by name",   
          SimpleBeanPropertyFilter.serializeAllExcept(  
              ignorableFieldNames));  
    ObjectWriter writer = mapper.writer(filters);  

    System.out.println(writer.writeValueAsString(new Bar()));  
    // output:  
    // {"name":"James","foo":{"size":"big","height":"tall"}}  
  }  
} 
Run Code Online (Sandbox Code Playgroud)

(注意:最近杰克逊发布的相关API可能略有变化.)

虽然该示例确实使用了看似不必要的注释,但注释不会应用于要排除的字段.(为了帮助更改API以简化必要的配置,请不要犹豫,投票支持JACKSON-274问题的实施.

  • 我搜索你需要的相同功能,给定的解决方案,如果对我的情况不够,因为使用建议将在嵌套对象中排除具有相同名称的字段.我想只在顶层排除它们.因此需要一种方法来指定属性必须被忽略的级别. (4认同)
  • 在 jackson 2.5.x 中,将 `mapper.getSerializationConfig().addMixInAnnotations( Object.class, PropertyFilterMixIn.class);` 替换为 `mapper.addMixIn(Object.class, PropertyFilterMixIn.class);` (4认同)
  • 有没有办法在道具中的某个地方存储过滤的项目,以便与Spring MVC一起使用,或者如何在Spring MVC中访问序列化流程? (3认同)

mon*_*jbl 11

我写了一个库来处理类似的用例.我需要以编程方式忽略基于请求数据的用户的字段.正常的杰克逊选择太过苛刻,我讨厌它使我的代码看起来的方式.

该库使这一点变得更容易理解.它允许您简单地执行此操作:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.monitorjbl.json.JsonView;
import com.monitorjbl.json.JsonViewSerializer;
import static com.monitorjbl.json.Match.match;

//initialize jackson
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

 //get a list of the objects
List<MyObject> list = myObjectService.list();

String json;
if(user.getRole().equals('ADMIN')){
    json = mapper.writeValueAsString(list);
} else {
    json = mapper.writeValueAsString(JsonView.with(list)
        .onClass(MyObject.class, match()
           .exclude("*")
           .include("name")));
}

System.out.println(json);
Run Code Online (Sandbox Code Playgroud)

代码可以在GitHub上获得,希望它有所帮助!


小智 7

如果您在两个或更多pojo上定义了过滤器,则可以尝试:

@JsonFilter("filterAClass") 
class AClass  
{       
  public String id = "42";  
  public String name = "Fred";  
  public String color = "blue";
  public int sal = 56;
  public BClass bclass = new BClass();  
}  

//@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonFilter("filterBClass") 
class BClass  
{  

  public String id = "99";  
  public String size = "90";  
  public String height = "tall";  
  public String nulcheck =null;  
}  
public class MultipleFilterConcept {
    public static void main(String[] args) throws Exception  
      {   
        ObjectMapper mapper = new ObjectMapper();
     // Exclude Null Fields
        mapper.setSerializationInclusion(Inclusion.NON_NULL);
        String[] ignorableFieldNames = { "id", "color" };  
        String[] ignorableFieldNames1 = { "height","size" };  
        FilterProvider filters = new SimpleFilterProvider()  
          .addFilter("filterAClass",SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames))
          .addFilter("filterBClass", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames1));  
        ObjectWriter writer = mapper.writer(filters);
       System.out.println(writer.writeValueAsString(new AClass())); 

      }
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*Man 6

对于像这样的大多数事情,杰克逊依赖于注释; 但您不必直接注释值类.您还可以使用"混合注释"(请参阅http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html).

除了基本@JsonIgnore(每个属性)或@JsonIgnoreProperties(每个类)之外,您还可以使用一些选项,请参阅http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html