Json中的自定义反序列化器

时间:2017-07-07 06:12:01

标签: java json jackson deserialization

我想在类级别下面的POJO中实现自定义Json映射。

@JsonDeserialize(using = DeviceDeserializer.class)
 public class Pojo {
   private String device;
   private String port;
   private String reservbleBw;
   *default constructor, getter and setters*
 }

以下是我的Json文件

[
  {
   "Device":"ABCD",
   "ifces":[
     {
      "port":"ABCD:1/2/0",
      "reservableBW":"1000",
      "capabilites":[ "MPLS" ]
    },
    {
      "port":"ABCD:1/2/1",
      "reservableBW":"100",
      "capabilites":[ "ETHERNET" ]
    }
  ]
 }
]

现在我只需要在'功能'为'ETHERNET'时映射端口和reservableBw。我查看了几个自定义反序列化器的示例,但我不知道如何传递JsonParser和DeserializationContext的值。我有理解以下问题。

  public Pojo deserialize(JsonParser jParser, DeserializationContext ctxt) throws IOException, JsonProcessingException
{
 // custom deserializer implementation
}

2 个答案:

答案 0 :(得分:0)

有两种方法可以解决您的问题:

方法1:使用中间对象映射:我已为您的问题创建了一个演示,请参阅this

创建一个中间对象以映射原始JSON

public class SfPojoDto {
    private String device;
    private List<Ifce> ifces;
}

public class Ifce {
    private String port;
    private String reservableBW;
    private String[] capabilites;
}

然后使用自定义反序列化器首先映射它并转换为目标对象。

public class DeviceDeserializer extends JsonDeserializer<SfPojo> {
    @Override
    public SfPojo deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        // while (p.nextToken()!=null) {
        //     if (p.getCurrentToken()==)
        // }
        String temp = p.readValueAsTree().toString();
        ObjectMapper mapper = new ObjectMapper();
        SfPojoDto sfPojoDto = mapper.readValue(temp, SfPojoDto.class);
        SfPojo sfPojo = new SfPojo();
        sfPojo.setDevice(sfPojoDto.getDevice());
        List<Ifce> ifceList = sfPojoDto.getIfces();
        for (Ifce ifce : ifceList) {
            List<String> capabilities = Arrays.asList(ifce.getCapabilites());
            if (capabilities.contains("ETHERNET")) {
                sfPojo.setPort(ifce.getPort());
                sfPojo.setReservbleBw(ifce.getReservableBW());
                return sfPojo;
            }
        }
        return sfPojo;
    }
}

方法2:你可以使用JsonParser来操作JSON字符串,但是这个方法比较复杂,你可以参考this article

答案 1 :(得分:0)

你的模特:

public class Ifce {

    public String port;
    public String reservableBW;
    public List<String> capabilites = null;

}

public class Device {
    public String device;
    public List<Ifce> ifces = null;

}

然后像这样使用objectMapper:

objectMapper = new ObjectMapper()
Device device = objectMapper.readValue(yourJsonData, Device.class)
List<Ifce> deviceList  = device.ifces.find { it.capabilites.contains("ETHERNET")}