使用jackson根据特定值排除json属性

时间:2015-11-12 07:11:44

标签: java json jackson

我有一个看起来像这样的json文件

{
  "items" : [ {
    "Name" : "India",
    "FullName" : "India",
    "Region" : "Asia"
  }, {
    "Name" : "USA",
    "FullName" : "United States of America",
    "Region" : "Americas"
  }, {
    "Name" : "UK",
    "FullName" : "United Kingdon",
    "DisplayLabel" : "Europe"
  } ]
}

Pojo类看起来像这样

Countries.java

package model;

import com.fasterxml.jackson.annotation.JsonProperty;
import javax.xml.bind.annotation.XmlElement;

public class Countries {

    @XmlElement( required = true )
    @JsonProperty( "Name" )
    private String name;

    @XmlElement( required = true )
    @JsonProperty( "FullName" )
    private String fullName;

    @XmlElement( required = true )
    @JsonProperty( "Region" )
    private String region;

    public Countries(@JsonProperty( "Name" ) String name, 
                 @JsonProperty( "FullName" ) String fullName,
                 @JsonProperty( "Region" ) String region) {
        this.name = name;
        this.fullName = fullName;
        this.region = region;
    }


    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getFullName() {
        return fullName;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public String getRegion() {
        return region;
    }
}

Items.java

package model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;

@JsonIgnoreProperties( ignoreUnknown = true )
public class Items {
    public Items() {
        super();
    }

    @XmlElement( required = true )
    @JsonProperty( "items" )
    protected List<Countries> view;


    public void setView(List<Countries> view) {
        this.view = view;
    }

    public List<Countries> getView() {
        return view;
    }

}

我正在使用jackson API。使用ObjectMapper序列化json。 防爆。

Items views = mapper.readValue(jsonString, Items.class);

我无法排除那些具有Region =&#34; Europe&#34;的条目。如何实现这一目标。提前谢谢。

2 个答案:

答案 0 :(得分:2)

Jackson应该专注于序列化和反序列化,而不是在该领域之外执行应用程序逻辑。最好不要反序列化内容,然后遍历对象以应用标准。

List<Country> nonEuropean = views.getView().stream()
        .filter(c -> !c.getRegion().equals("Europe"))
        .collect(Collectors.toList());

在架构上,保持Jackson包含的范围以将JSON转换为Java,反之亦然允许您在整个项目中使用相同的Jackson配置。在您当前的使用中,您希望省略欧洲国家/地区,但在应用程序的其他区域中,您可能希望包含这些实体。

答案 1 :(得分:1)

The best I could come with, is a custom Deserialiser that filters out regions (that obviously can come under either "Region" or "DisplayLabel") but the result collection will contain null entries that will require post processing to be removed:

Here is the complete custom Deserializer

package model;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

public class CountriesDeserializer extends JsonDeserializer<Countries> {
    @Override
    public Countries deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException
    {
        String region = null;
        JsonNode countryNode = p.getCodec().readTree(p);
        JsonNode regionNode = countryNode.get("Region");
        if (regionNode == null) regionNode = countryNode.get("DisplayLabel");
        if (regionNode != null) region = regionNode.asText();
        if ("Europe".equals(region) == false) {
            return new Countries(countryNode.get("Name").asText(), 
                    countryNode.get("FullName").asText(), region);
        }
        return null;
    }   
}

it needs to be specified on the collection property of Items class:

@XmlElement( required = true )
@JsonProperty( "items" )
@JsonDeserialize(contentUsing = CountriesDeserializer.class)
protected List<Countries> view;

the result of calling the ObjectMapper is a collection with one null entry.