本文介紹了如何識別杰克遜錯誤中缺失的類型ID?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我正在使用Jackson將JSON寫入文本文件,JSON表示從抽象類繼承的兩個類,但無論同時使用這兩個類還是使用其中一個/或類,錯誤都會發生。JSON似乎編寫正確,但在閱讀時,我收到以下錯誤:
Missing type id when trying to resolve subtype of [simple type, class model.BaseContact]: missing type id property 'type'
at [Source: (File); line: 52, column: 1]
json as follows:
{
"allContacts" : [ {
"type" : "personal",
"addressCity" : "Hamilton",
"addressNum" : "199",
"addressPOBox" : null,
"addressPostCode" : null,
"addressStreet" : "River Rd",
"addressSuburb" : null,
"email" : null,
"latitude" : null,
"longitude" : null,
"name" : "silly simon",
"notes" : null,
"phoneNumber" : "09754321",
"photoBytes" : null,
"photoURL" : null
}, {
"type" : "personal",
"addressCity" : "Auckland",
"addressNum" : "482",
"addressPOBox" : null,
"addressPostCode" : null,
"addressStreet" : "Smith Rd",
"addressSuburb" : null,
"email" : null,
"latitude" : null,
"longitude" : null,
"name" : "paul smith",
"notes" : null,
"phoneNumber" : "0544555",
"photoBytes" : null,
"photoURL" : null
}, {
"type" : "personal",
"addressCity" : "Appleby",
"addressNum" : "123",
"addressPOBox" : null,
"addressPostCode" : null,
"addressStreet" : "Apple rd",
"addressSuburb" : null,
"email" : null,
"latitude" : null,
"name" : "Steve Jobbs",
"notes" : null,
"phoneNumber" : "08004343",
"photoBytes" : null,
"photoURL" : null
} ],
"size" : 3
}
錯誤消息指向第52行第1列,假定調試器從第1行開始,這將是最后一個大括號后的行。
BaseContact
類頭如下:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=PersonContact.class, name= "personal"),
@JsonSubTypes.Type(value= BusinessContact.class, name="business")
})
public abstract class BaseContact {
public String name;
public String addressNum;
public String addressStreet;
public String addressSuburb;
public String addressCity;
public String addressPOBox;
public String addressPostCode;
public Double latitude;
public Double longitude;
public String photoURL;
public String photoBytes;
public String phoneNumber;
public String email;
public String notes;
public BaseContact() {
//DEFAULT CONSTRUCTOR
}
public BaseContact( String name, String addressNum, String addressStreet,
String addressCity, String phoneNumber) {
this.name = name;
this.addressNum = addressNum;
this.addressStreet = addressStreet;
this.addressCity = addressCity;
this.phoneNumber = phoneNumber;
}
調用函數如下:
public BusinessService readAllData(String fn) {
ArrayList<BaseContact> abl = new ArrayList<BaseContact>();
try {
abl = new ObjectMapper().readerFor(BaseContact.class).readValue(new File(fn));
Log.d("qq","abl"+ abl);
} catch (IOException e) {
Log.d("qq", "failed reading " + e.getMessage().toString());
e.printStackTrace();
}
BusinessService b = new BusinessService();
return b;
}
BusinessContact
類(繼承自抽象BaseContact
)如下:
package model;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property="type")
@JsonTypeName("type")
public class BusinessContact extends BaseContact {
public String companyName;
public String websiteURL;
public String businessHours;
//def constructor
public BusinessContact(){
};
public BusinessContact(String name, String addressNum, String addressStreet,
String addressCity, String phoneNumber, String companyName, String websiteURL, String businessHours) {
super(name, addressNum, addressStreet, addressCity, phoneNumber);
this.companyName = companyName;
this.websiteURL = websiteURL;
this.businessHours = businessHours;
}
//Getters and setters
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getWebsiteURL() {
return websiteURL;
}
public void setWebsiteURL(String websiteURL) {
this.websiteURL = websiteURL;
}
public String getBusinessHours() {
return businessHours;
}
public void setBusinessHours(String businessHours) {
this.businessHours = businessHours;
}
public String visitWebsite(int i ){
//get website, construct intent
return"url intent";
}
public Boolean isOpen(int i ){
//do math for day and time and return true if open
return true;
}
@Override
public String toString() {
String output= this.getClass() + "name: "+ this.name + " " + "company"+ this.companyName + "Hours "+ this.businessHours + "Website "+ this.websiteURL+ " address: " + this.addressNum+ " , " + this.addressStreet + " , " + this.addressSuburb+ "," +
this.addressCity +" , CODE " + this.addressPostCode + " PO BOX " + this.addressPOBox + "PH: " + this.phoneNumber + "email: " + this.email + "notes: "+ this.notes ;
return output ;
}
}
PersonContact
類(繼承自抽象BaseContact
):
package model;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonTypeName("type")
public class PersonContact extends BaseContact {
//constructor
public PersonContact(String name, String addressNum, String addressStreet, String addressCity, String phoneNumber) {
super(name, addressNum, addressStreet, addressCity, phoneNumber);
}
@Override
public String toString() {
String output = this.getClass() + "name: " + this.name + " " + " address: " + this.addressNum + " , " + this.addressStreet + " , " + this.addressSuburb + "," +
this.addressCity + " , CODE /n " + this.addressPostCode + " PO BOX " + this.addressPOBox + "PH: " + this.phoneNumber + "email: " + this.email + "notes: " + this.notes;
return output;
}
}
推薦答案
更新:
BusinessContact
類應該使用@JsonTypeName("business")
和PersonContact
類進行批注,而不是@JsonTypeName("type")
,因為您應該在繼承者中定義特定類型。
@JsonTypeInfo
注釋完全可以從子類中刪除。
更新2:
另外PersonContact
類應具有默認構造函數:
public PersonContact(){}
輸入JSON文件不是列表,它是具有allContacts
和size
兩個屬性的實體。因此,它不能映射到ArrayList<BaseContact>
。因此應該創建一個具有這兩個屬性的新實體:
public class ContactsWrapper
{
private List<BaseContact> allContacts;
private int size;
public List<BaseContact> getAllContacts()
{
return allContacts;
}
public void setAllContacts(List<BaseContact> allContacts)
{
this.allContacts = allContacts;
}
public int getSize()
{
return size;
}
public void setSize(int size)
{
this.size = size;
}
}
應更改讀取JSON的代碼:
ContactsWrapper contactsWrapper = new ObjectMapper().readerFor(ContactsWrapper.class).readValue(new File(fn));
abl = contactsWrapper.getAllContacts();
現在,JSON被映射到ContactsWrapper
,并使用getter將聯系人列表分配給abl
變量。
這篇關于如何識別杰克遜錯誤中缺失的類型ID?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,