JsonNode比较排除字段

时间:2018-11-03 12:44:04

标签: java json serialization jackson deserialization

我正在尝试使用ObjectMapper(杰克逊)反序列化JSON字符串,并在执行反序列化时排除字段。

我的代码如下:

String aContent = new String(Files.readAllBytes(Paths.get(aFile)));
String bContent = new String(Files.readAllBytes(Paths.get(bFile)));

ObjectMapper mapper = new ObjectMapper();

FilterProvider filterProvider = new SimpleFilterProvider()
      .addFilter("_idFilter", SimpleBeanPropertyFilter.serializeAllExcept("_id"));

mapper.setFilterProvider(filterProvider);

JsonNode tree1 = mapper.readTree(aContent);
JsonNode tree2 = mapper.readTree(bContent);

String x = mapper.writeValueAsString(tree1);

return tree1.equals(tree2);

x和tree1和tree2都在JSON字符串中包含值_id,但不会将其删除。

3 个答案:

答案 0 :(得分:1)

FilterProviderI edited the column names so you could see(table itself is in different language)这样的自定义对象一起使用

如果您想坚持使用JsonNode,请使用以下方法:

String aContent = new String("{\"a\":1,\"b\":2,\"_id\":\"id\"}"); 

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(aContent);
ObjectNode object = (ObjectNode) tree1;
object.remove(Arrays.asList("_id"));

System.out.println(mapper.writeValueAsString(object));

将打印:

{"a":1,"b":2}

答案 1 :(得分:1)

除了第一步之外,您正在关注Ignore Fields Using Filters

  

首先,我们需要在java对象上定义过滤器:

@JsonFilter("myFilter")
public class MyDtoWithFilter { ... }

所以目前您应该添加

@JsonFilter("_idFilter")
public class JsonNode {

不可能,因此您需要创建一个扩展JsonNode的类并改为使用它

@JsonFilter("_idFilter")
public class MyJsonNode extends JsonNode {

如果您不想实现所有抽象方法,请定义为abstract

@JsonFilter("_idFilter")
public abstract class MyJsonNode extends JsonNode {
}

在您的代码中:

MyJsonNode tree1 = mapper.readTree(aContent);
MyJsonNode tree2 = mapper.readTree(bContent);

答案 2 :(得分:0)

如果您使用Jackson 2.6或更高版本,则可以将FilteringParserDelegate与自定义TokenFilter一起使用。

public class PropertyBasedIgnoreFilter extends TokenFilter {

    protected Set<String> ignoreProperties;

    public PropertyBasedIgnoreFilter(String... properties) {
        ignoreProperties = new HashSet<>(Arrays.asList(properties));
    }

    @Override
    public TokenFilter includeProperty(String name) {
        if (ignoreProperties.contains(name)) {
            return null;
        }
        return INCLUDE_ALL;
    }
}

使用此FilteringParserDelegate创建PropertyBasedIgnoreFilter时,请确保将布尔值includePathallowMultipleMatches都设置为true

public class Main {
    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        String jsonInput = "{\"_p1\":1,\"_p2\":2,\"_id\":\"id\",\"_p3\":{\"_p3.1\":3.1,\"_id\":\"id\"}}";

        JsonParser filteredParser = new FilteringParserDelegate(mapper.getFactory().createParser(new ByteArrayInputStream(jsonInput.getBytes())),
                                                                new PropertyBasedIgnoreFilter("_id"),
                                                                true,
                                                                true);
        JsonNode tree = mapper.readTree(filteredParser);

        System.out.println(jsonInput);
        System.out.println(tree);
        System.out.println(jsonInput.equals(tree.toString()));
    }
}

打印

{"_p1":1,"_p2":2,"_id":"id","_p3":{"_p3.1":3.1,"_id":"id"}}
{"_p1":1,"_p2":2,"_p3":{"_p3.1":3.1,"_id":"id"}}
false

如您所见,_id的嵌套出现未被过滤掉。如果不需要的话,当然可以用自己的PropertyBasedIgnoreFilter实现扩展我的TokenFilter