将多数组json解析为POJO

时间:2017-01-08 13:10:53

标签: java json gson

我有一个生成的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类中需要做什么?

2 个答案:

答案 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>包含StringintbooleanJSONArray和另一个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泛型擦除,我们可以在这里任何
  • getNewsetNew方法应该提供并使用通配符列表,因为这里不能保证具体类。
  • Meta.fid 可能应声明为String(请参阅下面的反序列化程序进行重新映射,或者需要其他DTO类)。
  • Meta_.fid 可能也应该被声明为String(见下文 - 同样的原因)。

UnknownElement.java

这只是Gson的标记,以便在UnknownElement中为Cinfo应用特殊的反序列化器。请注意,Gson 尊重具有关于进一步反序列化的足够信息的字段的类型。但是,由于它只是一个标记,因此不能对其进行实例化或子类化(具有abstract构造函数的private类。

abstract class UnknownElement {

    private UnknownElement() {
    }

}

NameAndEmail.java

我在你的代码中没有找到这样的映射,所以我自己创建了它,尊重你问题中给定的JSON。

final class NameAndEmail {

    @SerializedName("name")
    @Expose
    private String name;

    @SerializedName("email")
    @Expose
    private String email;

    String getName() {
        return name;
    }

    String getEmail() {
        return email;
    }

}

UnknownElementDeserializer.java

这实际上是复杂解析的核心。首先,它是无状态的,并且不需要每个类加载器具有多个实例。其次,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");
    }

}

EntryPoint.java

演示本身读取并输出已破坏生成的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,以使它们按预期工作。