简体   繁体   English

Gson被读取到LinkedTreeMap中

[英]Gson being read into a LinkedTreeMap

I am having trouble with serializing JSON data. 我在序列化JSON数据时遇到麻烦。

So, I'm trying to use to generics, but somehow Gson hates me when I try to implement it. 因此,我尝试使用泛型,但是当我尝试实现它时,Gson讨厌我。 All I am trying to do is have basic abstraction with generics. 我要尝试做的就是具有泛型的基本抽象。 Here is my code: 这是我的代码:

Main class which does the generics part: 执行泛型部分的主类:

package com.yasinyazici.riot.config.json;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;

public abstract class JsonDataParser<T> {
    protected Gson gson = new Gson();
    protected String json;

    public JsonDataParser(String json) {
        this.json = json;
    }

    protected Map<String, T> transform() {
        Type type = new TypeToken<Map<String, T>>(){}.getType();
        return gson.fromJson(json, type);
    }

    public abstract T get();
}

Here is a child of the main class: 这是主要班级的孩子:

package com.yasinyazici.riot.config.json.impl;

import com.yasinyazici.riot.config.json.JsonDataParser;
import com.yasinyazici.riot.data.summoner.SummonerProperties;

public class SummonerPropertiesParser extends JsonDataParser<SummonerProperties> {
    public SummonerPropertiesParser(String json) {
        super(json);
    }

    @Override
    public SummonerProperties get() {
        transform().entrySet().forEach(p -> System.out.println(p.getValue().getProfileIconId()));
        return null;
    }
}

As you can see, IntelliJ even recognizes #get() as "SummonerProperties". 如您所见,IntelliJ甚至将#get()识别为“ SummonerProperties”。

That's my error: 那是我的错误:

Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.yasinyazici.riot.data.summoner.SummonerProperties
    at com.yasinyazici.riot.config.json.impl.SummonerPropertiesParser.lambda$get$0(SummonerPropertiesParser.java:17)
    at java.lang.Iterable.forEach(Iterable.java:75)
    at com.yasinyazici.riot.config.json.impl.SummonerPropertiesParser.get(SummonerPropertiesParser.java:17)
    at com.yasinyazici.riot.Main.main(Main.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

I am kinda confused. 我有点困惑。 If I print p (the object itself), I get the json in some weird format 如果我打印p(对象本身),则会以某种奇怪的格式获取json

jungleíslife={id=8.2249757E7, name=Jungle ís Life, profileIconId=1339.0, summonerLevel=30.0, revisionDate=1.481558959E12}

Original json looks like this: 原始json看起来像这样:

{"jungleíslife":{"id":82249757,"name":"Jungle ís Life","profileIconId":1339,"summonerLevel":30,"revisionDate":1481558959000}}

p#getValue() prints the body of the json. p#getValue()打印json的主体。 (in the weird format) (格式怪异)

So it seems like something is not being parsed correctly. 因此,似乎某些东西未正确解析。

Anyone? 任何人? Would appreciate any kind of help/solution. 将不胜感激任何帮助/解决方案。

EDIT: This is not an exact duplicate, reason for that is that I'm not trying to parameterize any Type, but rather need to get the original Type (I'm not using any Class variable to access a classes fields for parsing, neither do I want to). 编辑:这不是一个精确的重复,原因是我没有试图参数化任何Type,而是需要获取原始Type(我没有使用任何Class变量来访问要解析的class字段,我想)。

EDIT2: Alright, okay. EDIT2:好吧,好的。 Erm, I tried the example with Option 1 (see Linked question as reference), but I get the following (mind, I made the method #getRawType() in ListParameterizedType class return Map.class): 恩,我尝试了使用选项1的示例(请参阅链接的问题作为参考),但是我得到了以下提示(注意,我使ListParameterizedType类中的方法#getRawType()返回Map.class):

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1

Even if I keep it returning ArrayList, it throws me this: 即使我保留它返回ArrayList,它也会向我抛出以下内容:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

EDIT: Still got problems with that.. 编辑:仍然有问题。

EDIT2: Does NO ONE have a possible solution..? EDIT2:没有人有可能的解决方案..?

You will have to construct the TypeToken in the subclass, where the concrete type information is available. 您将必须在可提供具体类型信息的子类中构造TypeToken。 Add an abstract method to your superclass: 在您的超类中添加一个抽象方法:

protected abstract Type getType();

Change the parse method to use it: 更改分析方法以使用它:

protected Map<String, T> transform() {
    return gson.fromJson(json, getType());
}

Then override getType in your subclass to return the concrete type: 然后在子类中重写getType以返回具体类型:

@Override
protected Type getType() {
    return new TypeToken<Map<String, SummonerProperties>>(){}.getType();
}

Unrelated, but the "weird format" you see when you print getValue() isn't json, it's from Object.toString() . 无关,但是在打印getValue()时看到的“怪异格式”不是json,而是来自Object.toString()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM