Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson过滤出没有注释的字段_Java_Json_Jackson - Fatal编程技术网

Java Jackson过滤出没有注释的字段

Java Jackson过滤出没有注释的字段,java,json,jackson,Java,Json,Jackson,我试图通过SimpleBeanPropertyFilter使用以下(简化)代码从序列化中筛选出某些字段: 我使用的是SimpleBeanPropertyFilter.FilterOutalExcept(“data1”)我希望创建的序列化Json字符串只包含{“data1”:“value1”},但是我得到{“data1”:“value1”,“data2”:“value2”} 如何创建遵守指定筛选器的临时编写器(在我的情况下无法重新配置ObjectMapper) 注意:由于我的应用程序中的使用场景,

我试图通过
SimpleBeanPropertyFilter
使用以下(简化)代码从序列化中筛选出某些字段:

我使用的是
SimpleBeanPropertyFilter.FilterOutalExcept(“data1”)
我希望创建的序列化Json字符串只包含
{“data1”:“value1”}
,但是我得到
{“data1”:“value1”,“data2”:“value2”}

如何创建遵守指定筛选器的临时编写器(在我的情况下无法重新配置ObjectMapper)


注意:由于我的应用程序中的使用场景,我只能接受不使用Jackson注释的答案。

如果希望过滤器工作,您必须添加一个注释,说明在对bean类进行序列化时要使用哪个过滤器:

@JsonFilter("test")
public class Data {
    public String data1 = "value1";
    public String data2 = "value2";
}

编辑 OP刚刚添加了一个注释,回答是不使用bean动画,那么如果要导出的字段数量非常少,您可以自己检索该数据并构建列表的映射,似乎没有其他方法可以做到这一点

Map<String, Object> map = new HashMap<String, Object>();
map.put("data1", obj.getData1());
...
// do the serilization on the map object just created.
您可以定义宏是否导出或隐藏字段,如下所示:

@Since(GifMiaoMacro.GSON_SENSITIVE) //mark the field as sensitive data and will not export to JSON
private boolean firstFrameStored; // won't export this field to JSON.
 public static final double GSON_SENSITIVE = 2.0f;
 public static final double GSON_INSENSITIVE = 1.0f;
默认情况下,Gson将导出所有未由
@注释的字段,因为
因此,如果您不关心该字段,则无需执行任何操作,它只导出该字段

如果某个字段不想导出为json,即敏感信息,只需在该字段中添加注释即可。并使用以下命令生成json字符串:

 private static Gson gsonInsensitive = new GsonBuilder()
            .registerTypeAdapter(ObjectId.class,new ObjectIdSerializer()) // you can omit this line and the following line if you are not using mongodb
            .registerTypeAdapter(ObjectId.class, new ObjectIdDeserializer()) //you can omit this
            .setVersion(GifMiaoMacro.GSON_INSENSITIVE)
            .disableHtmlEscaping()
            .create();

public static String toInsensitiveJson(Object o){
    return gsonInsensitive.toJson(o);
}
那么就用这个:

 String jsonStr = StringUtils.toInsensitiveJson(yourObj);

由于Gson是无状态的,所以可以使用静态方法来完成您的工作,我已经尝试了许多使用Java的JSON序列化/反序列化框架,但发现Gson在性能和操作上都非常出色。

您通常会注释
数据
类以应用过滤器:

@JsonFilter("test")
class Data {
您已指定不能在类上使用批注。您可以使用mix-ins来避免注释
数据

@JsonFilter("test")
class DataMixIn {}
不能在
ObjectMapper
上指定mixin,您可以指定不想重新配置它。在这种情况下,您始终可以复制带有其配置的
ObjectMapper
,然后修改副本的配置。这不会影响代码中其他地方使用的原始
ObjectMapper
。例如

ObjectMapper myMapper = mapper.copy();
myMapper.addMixIn(Data.class, DataMixIn.class);
然后使用新的
ObjectMapper

String json = myMapper.writer(filterProvider).writeValueAsString(new Data());
System.out.println(json); // output: {"data1":"value1"}

按名称排除属性的示例:

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

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

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

mapper.writeValueAsString(user); // {"name":"abc"}
您可以代替
DynamicMixIn
create
MixInByPropName

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

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

mapper.writeValueAsString(user); // {"name":"abc"}
注意:如果您只想为
用户
排除属性,可以将方法
addMixIn
的参数
Object.class
更改为
User.class

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

@JsonIgnoreType
public class MixInByType {
}

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

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

如果出于某种原因,MixIns不适合你。您可以尝试以下方法:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
    @Override
    public boolean hasIgnoreMarker(final AnnotatedMember m) {

    List<String> exclusions = Arrays.asList("field1", "field2");
    return exclusions.contains(m.getName())|| super.hasIgnoreMarker(m);
    }
});
ObjectMapper ObjectMapper=new ObjectMapper();
objectMapper.setAnnotationIntrospector(新的JacksonAnnotationIntrospector(){
@凌驾
公共布尔hasIgnoreMarker(最终注释成员m){
列表排除=数组.asList(“field1”、“field2”);
返回Exclutions.contains(m.getName())| | super.hasIgnoreMarker(m);
}
});

很抱歉,但无法更改为Gson,我的大型应用程序基于Jackson,更改此项需要数周时间。此外,我还写道,我不能使用注释,您的答案基于要忽略的字段上的注释。顺便说一句,我不建议在另一个类文件中使用静态类,除非确实需要,即使有一个测试:dhijmax,我的答案有帮助吗?嗨,JMax。我注意到您在原始问题中添加了注释,因此我相应地更改了答案,请检查编辑。解决方案对我有效,只是我使用了“SimpleBeanPropertyFilter.serializeAllExcept”来排除不需要的属性,而不是“SimpleBeanPropertyFilter.FilterOutalExcept”这包括所有的,但指定的。正是我所寻找的,+1完美地工作。谢谢在过滤从couchbase获取的数据时使用此选项,而插入数据时无需过滤
@JsonIgnoreType
public class MixInByType {
}

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

mapper.writeValueAsString(user); // {"name":"abc"}
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
    @Override
    public boolean hasIgnoreMarker(final AnnotatedMember m) {

    List<String> exclusions = Arrays.asList("field1", "field2");
    return exclusions.contains(m.getName())|| super.hasIgnoreMarker(m);
    }
});