首页 > 解决方案 > 将具有属性的 Java 枚举序列化为 json 对象

问题描述

在 Java 中,将元属性添加到枚举类很简单:


public enum ItemType {

    NORMAL("Normal Item", 10, false),
    SPECIAL("Special Item", 20, false),
    RARE("Rare Item", 30, true);

    private final String description;
    private final int points;
    private final boolean magical;

    private ItemType(String description, int points, boolean magical) {
        this.description = description;
        this.points = points;
        this.magical = magical;
    }

    @Override
    public String toString() {
        return this.description;
    }

    public String getDescription() {
        return description;
    }

    public int getPoints() {
        return points;
    }

    public boolean isMagical() {
        return magical;
    }
}

我想序列化这些,但仅在某些休息端点按需序列化(即,在枚举名称转换为字符串的情况下,正常序列化仍应适用:NORMAL、、SPECIALRARE):

{
   "_enum": "NORMAL",
   "description": "Normal Item",
   "points": 10,
   "magical": false
}

有没有办法注释我的枚举,以便 gson 或 moshi 可以生成这样的 json 对象?还有其他解决方案吗?

标签: javagsonjax-rsmoshi

解决方案


我认为没有涵盖所有情况的通用解决方案。所有库,但这将是 gson 的解决方案

class ItemTypeAdapter extends TypeAdapter<ItemType> {

    private final String ENUM_ID = "_enum";

    @Override
    public void write(JsonWriter writer, ItemType itemType) throws IOException {
        writer.beginObject();
        writer.name(ENUM_ID).value(itemType.name());
        writer.name("description").value(itemType.getDescription());
        writer.name("points").value(itemType.getPoints());
        writer.name("magical").value(itemType.isMagical());
        writer.endObject();
    }

    @Override
    public ItemType read(JsonReader reader) throws IOException {
        String itemType = null;
        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if (name.equals(ENUM_ID)) {
                itemType = reader.nextString();
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();
        if (itemType != null) {
            return ItemType.valueOf(itemType);
        } else {
            throw new JsonParseException("Missing '" + ENUM_ID + "' value");
        }
    }
}

或者,您可以使用自定义JsonSerializer响应。JsonDeserializer. 要使用它,您需要在构建 gson 对象时将其注册为自定义类型适配器。其他库/框架可能有类似的解决方案


推荐阅读