如何用int和string创建GSON转换器

时间:2017-04-29 17:45:26

标签: android json gson retrofit

您好我遇到了创建GSON转换器来改造2

的问题

Api in" value"我得到了两个可能的参数,int和String。

所以你有时知道,当我下载一个String(除了int)时,我得到的错误如下:

java.lang.NumberFormatException:无效的double:" JACK"

我试图创建一个GSON转换器来防止JSON收到此错误,但我无法实现它。

我尝试使用方法:

public class StringTypeAdapter extends TypeAdapter<String> {


@Override
public void write(JsonWriter out, String value) throws IOException {
    if (Objects.equals(value, "ACE")) {
        value= String.valueOf(1);
        return;
    }
    out.value(value);
}

@Override
public String read(JsonReader in) throws IOException {
    if(in.peek() == JsonToken.NULL){
        in.nextNull();
        return null;
    }
    String stringValue = in.nextString();
    try{
        return String.valueOf(stringValue);
    }catch(NumberFormatException e){
        return null;
    }
}

}

但这不起作用。

我除外。

我想给出价值观 当

"ACE" = 1
"KING" = 2
"QUEEN" = 3
"JACK" = 4

有人可以帮助我吗?

这是我的班级卡:

public class Card {

    private String image;
    private int value;
    private String suit;
    private String code;
}

以下是JSON

的示例
{
"success": true,
"cards": [
    {
        "image": "https://deckofcardsapi.com/static/img/KH.png",
        "value": "KING",
        "suit": "HEARTS",
        "code": "KH"
    },
    {
        "image": "https://deckofcardsapi.com/static/img/8C.png",
        "value": "8",
        "suit": "CLUBS",
        "code": "8C"
    }
],
"deck_id":"3p40paa87x90",
"remaining": 50

}

我在这里宣布了这个课程:

  Gson gson = new GsonBuilder().registerTypeAdapter(String.class, new StringTypeAdapter()).create();
        retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

1 个答案:

答案 0 :(得分:1)

国王是否与两人发生冲突,不是吗?无论如何。您似乎不需要自定义适配器:您只需要适当的映射。首先,当您定义类型适配器时,您必须知道您覆盖所有类型用法。因此,当您定义字符串类型适配器时,它会影响所有字符串。其次,如果您拥有有限数量的元素,如卡片套装和卡片等级,您可以使用枚举:

enum Suit {

    @SuppressWarnings("SPADES") SPADES,
    @SerializedName("HEARTS") HEARTS,
    @SuppressWarnings("DIAMONDS") DIAMONDS,
    @SerializedName("CLUBS") CLUBS

}
enum Rank {

    @SerializedName("ACE") ACE,
    @SerializedName("KING") KING,
    @SerializedName("QUEEN") QUEEN,
    @SerializedName("JACK") JACK,
    @SerializedName("10") TEN,
    @SerializedName("9") NINE,
    @SerializedName("8") EIGHT,
    @SerializedName("7") SEVEN,
    @SerializedName("6") SIX,
    @SerializedName("5") FIVE,
    @SerializedName("4") FOUR,
    @SerializedName("3") THREE,
    @SerializedName("2") TWO

}

所以其余的映射可以按如下方式实现:

final class Card {

    @SerializedName("image") final URL image = null;
    @SerializedName("value") final Rank rank = null;
    @SerializedName("suit") final Suit suit = null;
    @SerializedName("code") final String code = null;

}

请注意,现在所有字段都是强类型的。您也可以让Rank返回code您的需要(只需在枚举中添加一个特定的代码字段并通过枚举构造函数初始化它)。如果由于任何可靠的原因您需要int字段,最好使用@JsonAdapter对字段进行注释,以使其更具体:

final class Card {

    @SerializedName("image") final URL image = null;
    @SerializedName("value") @JsonAdapter(RankTypeAdapter.class) final int rank = Integet.valueOf(0);
    @SerializedName("suit") final Suit suit = null;
    @SerializedName("code") final String code = null;

}
import static java.util.Arrays.asList;

final class RankTypeAdapter
        extends TypeAdapter<Integer> {

    private static final List<String> ranks = asList("ACE", "2", "3", "4", "5", "6", "7", "8", "9", "10", "JACK", "QUEEN", "KING");

    private RankTypeAdapter() {
    }

    @Override
    public void write(final JsonWriter out, final Integer value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Integer read(final JsonReader in)
            throws IOException {
        final String rank = in.nextString();
        final int index = ranks.indexOf(rank);
        if ( index == -1 ) {
            throw new MalformedJsonException("Cannot parse: " + rank + " at " + in);
        }
        return index + 1;
    }

}