我有一个生成的JSON,我想使用Gson
加载到普通的java类中这是JSON
{ “的errorCode”:0, “宿主”: “hg124.sg3”, “wssid”: “Cw8HBBq854C”, “数据”:{ “文件夹”:{ “元”:{ “FID”:0,”总 “:1,” 未读 “:2,” 大小 “:3,” 核心 “:4,其中” fname “:5”,totalConv “:6},” 文件夹 “:[[” 收件箱”,1,1, 6290,1, “收件箱”,1]], “新”:[] “删除”:[]}, “CID的”:[ “97247592121010”], “icids”:[ “97247592121010”], “cinfos” :{ “元”:{ “CID”:0 “ICID”:1, “CRC”:2 “总的”:3, “未读”:4 “日期”:5 “hasAttachment”:6,” hasDraft “:7,” flaggedMsgs “:8中,” participantList “:9,” 受试者 “:10,” 片断 “:11”,folderCounts “:12,” minfos “:13},” CINFO “:{” 新” :[[ “97247592121010”, “97247592121010”, “1293085011”,1,1,1483880495,FALSE,FALSE,0,[{ “名称”: “”, “电子邮件”: “name@aol.com”}], “喜”, “测试”,[{ “FID”: “收件箱”, “总”:1, “未读”:1}],{ “新”:[[ “AFSC8QoAAEnXWHI4LwZZAEo2ayM”, “AFSC8QoAAEnXWHI4LwZZAEo2ayM”,0,” name@aol.com”, “”, “喜”, “charlesesposito916@yahoo.com” 1483880495 “charlesesposito916@yahoo.com”,{ “片断”: “测试”}, “收件箱”, “收件箱”, “97247592121010”, “97247592121010”, “”]], “MOD”:[] “删除”:[]}]], “MOD”:[] “删除”:[]}}, “msgMeta”: { “中间”:0, “酰亚胺”:1, “标志”:2 “fromEmail”:3 “FROMNAME”:4“,苏bject “:5”,xapparentlyto “:6,” receivedDate “:7,” toEmail “:8中,” 片段 “:9”,FID “:10,其中” fname “:11,” CID “:12,” ICID” :13, “CSID”:14}, “flagBits”:{ “isReplied”:0 “isFlagged”:1, “isRead”:2 “isForwarded”:3 “hasAttachment”:4 “isCommercial”:5 “isYahoo”:6}}}
我使用http://www.jsonschema2pojo.org/生成POJO
-----------------------------------y.data.folderdata.Cinfo.java-----------------------------------
package y.data.folderdata;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Cinfo {
@SerializedName("new")
@Expose
private List<List<String>> _new = null;
@SerializedName("mod")
@Expose
private List<Object> mod = null;
@SerializedName("del")
@Expose
private List<Object> del = null;
public List<List<String>> getNew() {
return _new;
}
public void setNew(List<List<String>> _new) {
this._new = _new;
}
public List<Object> getMod() {
return mod;
}
public void setMod(List<Object> mod) {
this.mod = mod;
}
public List<Object> getDel() {
return del;
}
public void setDel(List<Object> del) {
this.del = del;
}
}
-----------------------------------y.data.folderdata.Cinfos.java-----------------------------------
package y.data.folderdata;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Cinfos {
@SerializedName("meta")
@Expose
private Meta_ meta;
@SerializedName("cinfo")
@Expose
private Cinfo cinfo;
public Meta_ getMeta() {
return meta;
}
public void setMeta(Meta_ meta) {
this.meta = meta;
}
public Cinfo getCinfo() {
return cinfo;
}
public void setCinfo(Cinfo cinfo) {
this.cinfo = cinfo;
}
}
-----------------------------------y.data.folderdata.Data.java-----------------------------------
package y.data.folderdata;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Data {
@SerializedName("folder")
@Expose
private Folder folder;
@SerializedName("cids")
@Expose
private List<String> cids = null;
@SerializedName("icids")
@Expose
private List<String> icids = null;
@SerializedName("cinfos")
@Expose
private Cinfos cinfos;
@SerializedName("msgMeta")
@Expose
private MsgMeta msgMeta;
@SerializedName("flagBits")
@Expose
private FlagBits flagBits;
public Folder getFolder() {
return folder;
}
public void setFolder(Folder folder) {
this.folder = folder;
}
public List<String> getCids() {
return cids;
}
public void setCids(List<String> cids) {
this.cids = cids;
}
public List<String> getIcids() {
return icids;
}
public void setIcids(List<String> icids) {
this.icids = icids;
}
public Cinfos getCinfos() {
return cinfos;
}
public void setCinfos(Cinfos cinfos) {
this.cinfos = cinfos;
}
public MsgMeta getMsgMeta() {
return msgMeta;
}
public void setMsgMeta(MsgMeta msgMeta) {
this.msgMeta = msgMeta;
}
public FlagBits getFlagBits() {
return flagBits;
}
public void setFlagBits(FlagBits flagBits) {
this.flagBits = flagBits;
}
}
-----------------------------------y.data.folderdata.FlagBits.java-----------------------------------
package y.data.folderdata;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class FlagBits {
@SerializedName("isReplied")
@Expose
private Integer isReplied;
@SerializedName("isFlagged")
@Expose
private Integer isFlagged;
@SerializedName("isRead")
@Expose
private Integer isRead;
@SerializedName("isForwarded")
@Expose
private Integer isForwarded;
@SerializedName("hasAttachment")
@Expose
private Integer hasAttachment;
@SerializedName("isCommercial")
@Expose
private Integer isCommercial;
@SerializedName("isYahoo")
@Expose
private Integer isYahoo;
public Integer getIsReplied() {
return isReplied;
}
public void setIsReplied(Integer isReplied) {
this.isReplied = isReplied;
}
public Integer getIsFlagged() {
return isFlagged;
}
public void setIsFlagged(Integer isFlagged) {
this.isFlagged = isFlagged;
}
public Integer getIsRead() {
return isRead;
}
public void setIsRead(Integer isRead) {
this.isRead = isRead;
}
public Integer getIsForwarded() {
return isForwarded;
}
public void setIsForwarded(Integer isForwarded) {
this.isForwarded = isForwarded;
}
public Integer getHasAttachment() {
return hasAttachment;
}
public void setHasAttachment(Integer hasAttachment) {
this.hasAttachment = hasAttachment;
}
public Integer getIsCommercial() {
return isCommercial;
}
public void setIsCommercial(Integer isCommercial) {
this.isCommercial = isCommercial;
}
public Integer getIsYahoo() {
return isYahoo;
}
public void setIsYahoo(Integer isYahoo) {
this.isYahoo = isYahoo;
}
}
-----------------------------------y.data.folderdata.Folder.java-----------------------------------
package y.data.folderdata;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Folder {
@SerializedName("meta")
@Expose
private Meta meta;
@SerializedName("folders")
@Expose
private List<List<String>> folders = null;
@SerializedName("new")
@Expose
private List<Object> _new = null;
@SerializedName("del")
@Expose
private List<Object> del = null;
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
public List<List<String>> getFolders() {
return folders;
}
public void setFolders(List<List<String>> folders) {
this.folders = folders;
}
public List<Object> getNew() {
return _new;
}
public void setNew(List<Object> _new) {
this._new = _new;
}
public List<Object> getDel() {
return del;
}
public void setDel(List<Object> del) {
this.del = del;
}
}
-----------------------------------y.data.folderdata.FolderData.java-----------------------------------
package y.data.folderdata;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class FolderData {
@SerializedName("errorCode")
@Expose
private Integer errorCode;
@SerializedName("host")
@Expose
private String host;
@SerializedName("wssid")
@Expose
private String wssid;
@SerializedName("data")
@Expose
private Data data;
public Integer getErrorCode() {
return errorCode;
}
public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getWssid() {
return wssid;
}
public void setWssid(String wssid) {
this.wssid = wssid;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
}
-----------------------------------y.data.folderdata.Meta.java-----------------------------------
package y.data.folderdata;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Meta {
@SerializedName("fid")
@Expose
private Integer fid;
@SerializedName("total")
@Expose
private Integer total;
@SerializedName("unread")
@Expose
private Integer unread;
@SerializedName("size")
@Expose
private Integer size;
@SerializedName("core")
@Expose
private Integer core;
@SerializedName("fname")
@Expose
private Integer fname;
@SerializedName("totalConv")
@Expose
private Integer totalConv;
public Integer getFid() {
return fid;
}
public void setFid(Integer fid) {
this.fid = fid;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getUnread() {
return unread;
}
public void setUnread(Integer unread) {
this.unread = unread;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public Integer getCore() {
return core;
}
public void setCore(Integer core) {
this.core = core;
}
public Integer getFname() {
return fname;
}
public void setFname(Integer fname) {
this.fname = fname;
}
public Integer getTotalConv() {
return totalConv;
}
public void setTotalConv(Integer totalConv) {
this.totalConv = totalConv;
}
}
-----------------------------------y.data.folderdata.Meta_.java-----------------------------------
package y.data.folderdata;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Meta_ {
@SerializedName("cid")
@Expose
private Integer cid;
@SerializedName("icid")
@Expose
private Integer icid;
@SerializedName("crc")
@Expose
private Integer crc;
@SerializedName("total")
@Expose
private Integer total;
@SerializedName("unread")
@Expose
private Integer unread;
@SerializedName("date")
@Expose
private Integer date;
@SerializedName("hasAttachment")
@Expose
private Integer hasAttachment;
@SerializedName("hasDraft")
@Expose
private Integer hasDraft;
@SerializedName("flaggedMsgs")
@Expose
private Integer flaggedMsgs;
@SerializedName("participantList")
@Expose
private Integer participantList;
@SerializedName("subject")
@Expose
private Integer subject;
@SerializedName("snippet")
@Expose
private Integer snippet;
@SerializedName("folderCounts")
@Expose
private Integer folderCounts;
@SerializedName("minfos")
@Expose
private Integer minfos;
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Integer getIcid() {
return icid;
}
public void setIcid(Integer icid) {
this.icid = icid;
}
public Integer getCrc() {
return crc;
}
public void setCrc(Integer crc) {
this.crc = crc;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getUnread() {
return unread;
}
public void setUnread(Integer unread) {
this.unread = unread;
}
public Integer getDate() {
return date;
}
public void setDate(Integer date) {
this.date = date;
}
public Integer getHasAttachment() {
return hasAttachment;
}
public void setHasAttachment(Integer hasAttachment) {
this.hasAttachment = hasAttachment;
}
public Integer getHasDraft() {
return hasDraft;
}
public void setHasDraft(Integer hasDraft) {
this.hasDraft = hasDraft;
}
public Integer getFlaggedMsgs() {
return flaggedMsgs;
}
public void setFlaggedMsgs(Integer flaggedMsgs) {
this.flaggedMsgs = flaggedMsgs;
}
public Integer getParticipantList() {
return participantList;
}
public void setParticipantList(Integer participantList) {
this.participantList = participantList;
}
public Integer getSubject() {
return subject;
}
public void setSubject(Integer subject) {
this.subject = subject;
}
public Integer getSnippet() {
return snippet;
}
public void setSnippet(Integer snippet) {
this.snippet = snippet;
}
public Integer getFolderCounts() {
return folderCounts;
}
public void setFolderCounts(Integer folderCounts) {
this.folderCounts = folderCounts;
}
public Integer getMinfos() {
return minfos;
}
public void setMinfos(Integer minfos) {
this.minfos = minfos;
}
}
-----------------------------------y.data.folderdata.MsgMeta.java-----------------------------------
package y.data.folderdata;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class MsgMeta {
@SerializedName("mid")
@Expose
private Integer mid;
@SerializedName("imid")
@Expose
private Integer imid;
@SerializedName("flags")
@Expose
private Integer flags;
@SerializedName("fromEmail")
@Expose
private Integer fromEmail;
@SerializedName("fromName")
@Expose
private Integer fromName;
@SerializedName("subject")
@Expose
private Integer subject;
@SerializedName("xapparentlyto")
@Expose
private Integer xapparentlyto;
@SerializedName("receivedDate")
@Expose
private Integer receivedDate;
@SerializedName("toEmail")
@Expose
private Integer toEmail;
@SerializedName("snippet")
@Expose
private Integer snippet;
@SerializedName("fid")
@Expose
private Integer fid;
@SerializedName("fname")
@Expose
private Integer fname;
@SerializedName("cid")
@Expose
private Integer cid;
@SerializedName("icid")
@Expose
private Integer icid;
@SerializedName("csid")
@Expose
private Integer csid;
public Integer getMid() {
return mid;
}
public void setMid(Integer mid) {
this.mid = mid;
}
public Integer getImid() {
return imid;
}
public void setImid(Integer imid) {
this.imid = imid;
}
public Integer getFlags() {
return flags;
}
public void setFlags(Integer flags) {
this.flags = flags;
}
public Integer getFromEmail() {
return fromEmail;
}
public void setFromEmail(Integer fromEmail) {
this.fromEmail = fromEmail;
}
public Integer getFromName() {
return fromName;
}
public void setFromName(Integer fromName) {
this.fromName = fromName;
}
public Integer getSubject() {
return subject;
}
public void setSubject(Integer subject) {
this.subject = subject;
}
public Integer getXapparentlyto() {
return xapparentlyto;
}
public void setXapparentlyto(Integer xapparentlyto) {
this.xapparentlyto = xapparentlyto;
}
public Integer getReceivedDate() {
return receivedDate;
}
public void setReceivedDate(Integer receivedDate) {
this.receivedDate = receivedDate;
}
public Integer getToEmail() {
return toEmail;
}
public void setToEmail(Integer toEmail) {
this.toEmail = toEmail;
}
public Integer getSnippet() {
return snippet;
}
public void setSnippet(Integer snippet) {
this.snippet = snippet;
}
public Integer getFid() {
return fid;
}
public void setFid(Integer fid) {
this.fid = fid;
}
public Integer getFname() {
return fname;
}
public void setFname(Integer fname) {
this.fname = fname;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Integer getIcid() {
return icid;
}
public void setIcid(Integer icid) {
this.icid = icid;
}
public Integer getCsid() {
return csid;
}
public void setCsid(Integer csid) {
this.csid = csid;
}
}
}
但是当我尝试使用下面的代码将json加载到POJO类时,我得到以下异常
FolderData folderData = gson.fromJson(jsonContent.toString(), y.data.folderdata.FolderData.class);
例外是:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 561 path $.data.cinfos.cinfo.new[0][9]
我怀疑这是因为“new”中的数组没有名字?如何成功将其加载到POJO类中需要做什么?
答案 0 :(得分:1)
Cinfo内的_new
不是List<List<String>>
。这是你的cinfo:
{
"new": [
["97247592121010", "97247592121010", "1293085011", 1, 1, 1483880495, false, false, 0, [{
"name": "",
"email": "name@aol.com"
}], "hi", "test", [{
"fid": "Inbox",
"total": 1,
"unread": 1
}], {
"new": [
["AFSC8QoAAEnXWHI4LwZZAEo2ayM", "AFSC8QoAAEnXWHI4LwZZAEo2ayM", 0, "name@aol.com", "", "hi", "charlesesposito916@yahoo.com", 1483880495, "charlesesposito916@yahoo.com", {
"snippet": "test"
}, "Inbox", "Inbox", "97247592121010", "97247592121010", ""]
],
"mod": [],
"del": []
}]
],
"mod": [],
"del": []
}
_new
内的Cinfo
实际上是List<List<Object>>
,内部List<Object>
包含String
,int
,boolean
,JSONArray
和另一个Cinfo Object
。
对于您的问题,您可以通过将类Cinfo的_new
修改为List<List<Object>>
来成功加载此JSON,如下所示:
@SerializedName("new")
@Expose
private List<List<Object>> _new = null;
但如果您想有效地访问这些数据,您仍需要找到解析此List<List<Object>>
的方法。
答案 1 :(得分:0)
我有点晚了。
由于对给定JSON的更复杂分析,这些POJO生成器很弱,因为它们不处理多态 DTO属性。这些属性还需要自定义反序列化器才能正确地反序列化这些属性。
首先,生成的POJO有一些问题:
List<List<String>> _new
声明为某些未知类列表的列表,Gson可以看到这些列表以应用反序列化策略。比如,List<List<UnknownElement>> _new
- 足够使Gson正常工作,但由于Java泛型擦除,我们可以在这里任何。getNew
和setNew
方法应该提供并使用通配符列表,因为这里不能保证具体类。Meta.fid
可能应声明为String
(请参阅下面的反序列化程序进行重新映射,或者需要其他DTO类)。Meta_.fid
可能也应该被声明为String
(见下文 - 同样的原因)。这只是Gson的标记,以便在UnknownElement
中为Cinfo
应用特殊的反序列化器。请注意,Gson 尊重具有关于进一步反序列化的足够信息的字段的类型。但是,由于它只是一个标记,因此不能对其进行实例化或子类化(具有abstract
构造函数的private
类。
abstract class UnknownElement {
private UnknownElement() {
}
}
我在你的代码中没有找到这样的映射,所以我自己创建了它,尊重你问题中给定的JSON。
final class NameAndEmail {
@SerializedName("name")
@Expose
private String name;
@SerializedName("email")
@Expose
private String email;
String getName() {
return name;
}
String getEmail() {
return email;
}
}
这实际上是复杂解析的核心。首先,它是无状态的,并且不需要每个类加载器具有多个实例。其次,Gson支持基于TypeToken
的非常酷的类型推断功能,它可以保存复杂的类型参数化,其中任何类型都可以保持,而不像Class
。第三,反序列化方法试图对多态属性进行简单分析,并返回 Object
实例而不是UnknownElement
。请注意,下面构建的Gson将仅绑定到此类,并且不会实例化任何UnknownElement
实例 - 虚拟类只是一个不可实例化的标记。
final class UnknownElementDeserializer
implements JsonDeserializer<Object> {
private UnknownElementDeserializer() {
}
private static final JsonDeserializer<Object> unknownElementDeserializer = new UnknownElementDeserializer();
private static final Type listOfUnknownElementsType = new TypeToken<List<UnknownElement>>() {
}.getType();
static JsonDeserializer<Object> getUnknownElementDeserializer() {
return unknownElementDeserializer;
}
@Override
public Object deserialize(final JsonElement element, final Type type, final JsonDeserializationContext context) {
if ( element.isJsonNull() ) {
return null;
}
if ( element.isJsonPrimitive() ) {
return context.deserialize(element, String.class);
}
if ( element.isJsonObject() ) {
final JsonObject object = element.getAsJsonObject();
if ( isNameAndEmail(object) ) {
return context.deserialize(element, NameAndEmail.class);
}
if ( isMeta_(object) ) {
return context.deserialize(object, Meta_.class);
}
if ( isMeta(object) ) {
return context.deserialize(element, Meta.class);
}
if ( isCinfo(object) ) {
return context.deserialize(object, Cinfo.class);
}
throw new JsonParseException("Can't parse: " + element);
}
if ( element.isJsonArray() ) {
return context.deserialize(element, listOfUnknownElementsType);
}
throw new AssertionError("Must never happen");
}
private static boolean isCinfo(final JsonObject object) {
return object.has("new") && object.has("del");
}
private static boolean isMeta(final JsonObject object) {
return object.has("fid") && object.has("total") && object.has("unread");
}
private static boolean isMeta_(final JsonObject object) {
return object.has("snippet");
}
private static boolean isNameAndEmail(final JsonObject object) {
return object.has("name") && object.has("email");
}
}
演示本身读取并输出已破坏生成的POJO的$.data.cinfos.cinfo.new
。
public final class EntryPoint {
private EntryPoint() {
}
public static void main(final String... args)
throws IOException {
final Gson gson = new GsonBuilder()
.registerTypeAdapter(UnknownElement.class, getUnknownElementDeserializer())
.create();
try ( final InputStream inputStream = EntryPoint.class.getClassLoader().getResourceAsStream("q41533067/test.json");
final Reader reader = new InputStreamReader(inputStream) ) {
final FolderData folderData = gson.fromJson(reader, FolderData.class);
Stream.of(folderData.getData().getCinfos().getCinfo().getNew())
.flatMap(Collection::stream)
.flatMap((Function<List<?>, Stream<?>>) Collection::stream)
.flatMap(o -> o == null ? empty()
: o instanceof Collection ? ((Collection<?>) o).stream()
: Stream.of(o)
)
.forEach(out::println);
}
}
}
输出:
97247592121010
97247592121010
1293085011个
1
1
1483880495个
假
假
0
q41533067.NameAndEmail@71dac704
喜
测试
q41533067.Meta@123772c4
q41533067.Cinfo@2d363fb3
不要相信自动化POJO生成器,并考虑重新生成生成的POJO,以使它们按预期工作。