如何使用Jackson检索具有不同值类型的JSON

时间:2018-01-19 17:02:13

标签: java json jackson

我正在使用Jackson对来自外部API的JSON文件进行反序列化,不幸的是,这个文件无法改变。

这个JSON有related属性的两个可能值:一个作为列表,当它被填充时:

"related": [{
        "ID": "1694"
    }, {
        "ID": "1631"
    }, {
        "ID": "1628"
}]

false如果不是。

"related": [false]

在第二种情况下,我收到JsonMappingException

Could not read document: Can not construct instance of xxx.xxx.xxx.RelatedDTO: 
no boolean/Boolean-argument constructor/factory method to deserialize from boolean value (false) 

如何管理这两个可能的值?

这就是我现在所拥有的。

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.time.LocalDateTime;
import java.util.List;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
@SuppressWarnings("all")
public class MagazinePostDTO {

    private List<MagazineRelatedDTO> related;

    // other properties....

}

MagazineRelatedDTO是:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
@SuppressWarnings("all")
public class MagazineRelatedDTO {

    @JsonProperty("ID")
    private Integer id;

} 

3 个答案:

答案 0 :(得分:0)

IMO,您可以在异常的情况下读取try块中的属性,即失败案例,阅读Boolean对象。

try
{
   // code here and store to POJO
   MagazinePostDTO postDTO = objectMapper.readValue(jsonData, MagazinePostDTO.class);
   // some coding
}
catch (JsonMappingException e)
{
    //failure case, read Boolean 
    Boolean bool = objectMapper.readValue(jsonData, Boolean.class);
    // some coding 
}

答案 1 :(得分:0)

就像错误消息所暗示的那样,你可以为newDefaultDirectory建立一个布尔参数构造函数。在此构造函数中,您可以为MagazineRelatedDTO属性设置一些默认值,甚至不执行任何操作,在这种情况下,id将使用包含一个具有空MagazinePostDTO属性的项的列表进行初始化

id

答案 2 :(得分:0)

我用custom deserializer解决了:如果我无法正确反序列化,我会返回一个空对象。

public class RelatedDeserializer extends JsonDeserializer<MagazineRelatedDTO> {

    @Override
    public MagazineRelatedDTO deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        try {
            MagazineRelatedDTO value = p.readValueAs(new TypeReference<MagazineRelatedDTO>() {});
            return value;
        } catch (Exception e) {
            return new MagazineRelatedDTO();
        }
    }
}

然后你必须在你的DTO中定义它。

@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
@SuppressWarnings("all")
public class MagazinePostDTO {

    @JsonDeserialize(contentUsing = RelatedDeserializer.class)
    private List<MagazineRelatedDTO> related;
    // other properties....

}