如何使用Gson库反序列化一个List<Generic<Enum>>?

huangapple 未分类评论47阅读模式
英文:

how to De-serialize a List<Generic<Enum>> using Gson library

问题

我需要将这个 Json 字符串反序列化为一个 POJO普通 Java 对象)。

Json:

    [
        {
            "first": {
                "value": 12,
                "suit": {
                    "name": "heart"
                }
            },

            "second": {
                "value": 12,
                "suit": {
                    "name": "spade"
                }
            }
        },
        {
            "first": {
                "value": 8,
                "suit": {
                    "name": "club"
                }
            },
            "second": {
                "value": 9,
                "suit": {
                    "name": "club"
                }
            }
        }
    ]

我正在尝试将这个 json 字符串反序列化为一个 `ArrayList<Pair<Card>>`,其中 `Pair<?>` 类是泛型`Card` 类是一个枚举

我尝试使用以下方法进行

    Type listType = new TypeToken<ArrayList<Pair<Card>>>(){}.getType();
    List<Pair<Card>> handList = gson.fromJson(hands, listType);

Card 类

```java
public enum Card {

    @SerializedName("value")
    public int value;
    @SerializedName("suit")
    public Suit suit;

    Card(int value, Suit suit) {
        this.value = value;
        this.suit = suit;
    }
}

Suit 类:

public enum Suit {

    @SerializedName("name")
    public String name;

    Suit(String name) {
        this.name = name;
    }
}

然而 Gson 一直抛出 IllegalStateException 异常:

java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 3 column 15 path $[0].first
英文:

I need to De-serialize this Json string into a POJO.

Json:

[
	{
		&quot;first&quot; : {
			&quot;value&quot; : 12,
			&quot;suit&quot; :  {
				&quot;name&quot; : &quot;heart&quot;
			}
		},

		&quot;second&quot; : {
			&quot;value&quot; : 12,
			&quot;suit&quot; : {
				&quot;name&quot; : &quot;spade&quot;
			}
		}
	},
	{
		&quot;first&quot; : {
			&quot;value&quot; : 8,
			&quot;suit&quot; : {
				&quot;name&quot; : &quot;club&quot;
			}
		},
		&quot;second&quot; : {
			&quot;value&quot; : 9,
			&quot;suit&quot; : {
				&quot;name&quot; : &quot;club&quot;
			}
		}
	}
]

I am trying to de-serialize this json string to a ArrayList&lt;Pair&lt;Card&gt;&gt; where the Pair&lt;?&gt; class is generic and the Card class is an enum.

I am attempting to do this via the following:

Type listType = new TypeToken&lt;ArrayList&lt;Pair&lt;Card&gt;&gt;&gt;(){}.getType();
List&lt;Pair&lt;Card&gt;&gt; handList = gson.fromJson(hands, listType);

Card class:

public enum Card {


@SerializedName(&quot;value&quot;)
public int value;
@SerializedName(&quot;suit&quot;)
public Suit suit;

Card(int value, Suit suit) {
    this.value = value;
    this.suit = suit;
}

Suit class:

public enum Suit {


@SerializedName(&quot;name&quot;)
public String name;

Suit(String name) {
    this.name = name;
}

}

However Gson keeps throwing IllegalStateException's

java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 3 column 15 path $[0].first

答案1

得分: 0

你可以为 Card 类创建一个自定义的反序列化器(Deserializer):

public class CardDeserializer implements JsonDeserializer<Card> {
    @Override
    public Card deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject obj = json.getAsJsonObject();
        JsonObject jobject = obj.getAsJsonObject("suit");
        // 在这里使用这些值创建 Card 对象
        // obj.get("value").getAsString();
        // jobject.get("name").getAsString();
        // ...
        return card;
    }
}

然后在使用之前在 Gson 构建器中注册该反序列化器:

gson.registerTypeAdapter(Card.class, new CardDeserializer());
英文:

You can create a custom Deserializer for Card class

public class CardDeserializer implements JsonDeserializer&lt;Card&gt; {
    @Override
    public Card deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject obj = json.getAsJsonObject();
        JsonObject jobject = obj.getAsJsonObject(&quot;suit&quot;);
        //Create Card here using those value
        //obj.get(&quot;value&quot;).getAsString();
        //jobject.get(&quot;name&quot;).getAsString();
        ...
        return card;
    }
}

And register in gson builder before work

gson.registerTypeAdapter(Card.class, new CardDeserializer());

huangapple
  • 本文由 发表于 2020年7月25日 01:36:05
  • 转载请务必保留本文链接:https://java.coder-hub.com/63078726.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定