我正在调用可以在响应中包含2种类型的json对象的Web服务。现在,有时我会得到profile
类型为String的密钥,有时它可能具有与'ProfileSubObject'类型相同的密钥。那么如何处理这种情况呢?以下是我的两种对象。我正在使用Jackson库解析json。
1.)
{
"data": [
{
"profession": "iOS Developer",
"thanks": {
"count": 5
},
"profile": "test"
}
]
}
2.)
{
"data": [
{
"profession": "iOS Developer",
"thanks": {
"count": 5
},
"profile": {
"val1":"test1",
"val2":"test2"
}
}
]
}
密钥profile
基于Web服务调用具有2种不同类型的对象。
以下是我的数据类结构。
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class DataObject {
@JsonProperty("profession")
private String profession;
@JsonProperty("profile")
private ProfileObject profile;
@JsonProperty("thanks")
private ThanksObject thanks;
public String getProfession() {
return profession;
}
public ThanksObject getThanks() {
return thanks;
}
public ProfileObject getProfile() {
return profile;
}
}
和Profile类如下。
public class ProfileObject {
ProfileObject(){
}
ProfileObject(ProfileSubObject profileSubObject){
this.profileSubObject= profileSubObject;
}
ProfileObject(String profile){
this.profile= profile;
}
private ProfileSubObject profileSubObject;
private String profile;
public ProfileSubObject getProfileSubObject() {
return profileSubObject;
}
}
现在,当我解析对象时,ProfileObject
始终为null。我希望它根据proifle
关键数据类型进行解析。
有人可以帮我解析吗?
在构建解决方案时,我面临两个问题:
DataObject
我通过构造JavaType
对象来解决第一个问题,该对象告诉Jackson所涉及集合的通用类型。有两个这样的集合:一Map
,由与主要单个条目"data"
和价值List
的DataObject
小号
第二个问题,我使用杰克逊(Jackson)功能解决,该功能@JsonAnySetter
指示杰克逊(Jackson)为所有无法识别的属性调用一个方法。为此,我添加@JsonIgnore
了配置文件变量以确保Jackson确实无法识别它。现在,杰克逊为两个输入json调用相同的方法
这是新DataObject
类:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class DataObject
{
@JsonProperty("profession")
public String profession;
@JsonIgnore // forcing jackson to not recognize this property
public ProfileObject profile;
@JsonProperty("thanks")
public ThanksObject thanks;
public String getProfession() { return profession; }
public void setProfession(String p) { profession = p; }
public ThanksObject getThanks() { return thanks; }
public void setThanks(ThanksObject t) { thanks = t; }
public ProfileObject getProfile() { return profile; }
public void setProfile(ProfileObject p) { profile = p; }
@JsonAnySetter
public void setProfileFromJson(String name, Object value)
{
// if value is single String, call appropriate ctor
if (value instanceof String) {
profile = new ProfileObject((String)value);
}
// if value is map, it must contain 'val1', 'val2' entries
if (value instanceof Map) {
ProfileSubObject profileSubObject =
new ProfileSubObject(((Map<String, String>)value).get("val1"), ((Map<String, String>)value).get("val2"));
profile = new ProfileObject(profileSubObject);
}
// error?
}
}
这是我的测试方法,其中包括我提到的Java类型构造:
public static void main(String[] args)
{
try (Reader reader = new FileReader("C://Temp/xx2.json")) {
ObjectMapper mapper = new ObjectMapper();
// type of key of map is String
JavaType stringType = TypeFactory.defaultInstance().constructType(String.class);
// type of value of map is list of DataObjects
JavaType listOfDataObject = TypeFactory.defaultInstance().constructCollectionType(List.class, DataObject.class);
// finally, construct map type with key and value types
JavaType rootMap = TypeFactory.defaultInstance().constructMapType(HashMap.class, stringType, listOfDataObject);
Map<String ,List<DataObject>> m = mapper.readValue(reader, rootMap);
DataObject do1 = m.values()
// get first (only?) value in map (it is list)
.stream().findFirst().orElse(Collections.emptyList())
// get first (only?) item in list - it is the DataObject
.stream().findFirst().orElse(null);
System.out.println(do1.profile);
System.out.println(do1.profile.profile);
System.out.println(do1.profile.profileSubObject.val1 + " " + do1.profile.profileSubObject.val2);
} catch (Exception e) {
e.printStackTrace();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句