如何制作符合i18n标准的EnumTypeAdapter?

时间:2015-08-07 19:32:37

标签: java enums internationalization gson

我正在通过Gson反序列化(.toJson)为Enums国际化提供一个很好的解决方案。

现在我有了:

private static final class GenericEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {

    private ResourceBundle bundle = ResourceBundle.getBundle("Messages");

    private Class<T> classOfT;

    public GenericEnumTypeAdapter(Class<T> classOfT) {
        this.classOfT = classOfT;
    }

    public T read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        return Enum.valueOf(classOfT, in.nextString());
    }

    public void write(JsonWriter out, T value) throws IOException {
        out.value(value == null ? null : bundle.getString("enum." + value.getClass().getSimpleName() + "."
                + value.name()));
    }
}

此解决方案的问题是:对于每个枚举,您应该注册一个新的适配器:

gsonBuilder.registerTypeAdapter(EventSensorState.class,
    new GenericEnumTypeAdapter<>(FirstEnum.class)

有人有想法做得更好吗?

1 个答案:

答案 0 :(得分:0)

使用TypeAdapterFactory生成所有适配器。请参阅 How do I implement TypeAdapterFactory in Gson?

要将TypeAdapter转换为TypeAdapterFactory,关键是正确检测课程,然后使用create方法。警告:此解决方案将在您的系统中注册每种类型的枚举;您可能必须将其调整为仅与实现特定接口的Enum一起使用,或者使用子类注册Enum类等。我创建了一个EnumGenerator类来执行大部分操作阅读转换的工作,你应该能够自己弄清楚。

public class EnumAdapterFactory implements TypeAdapterFactory {
  private final ResourceBundle bundle;
  private final EnumGenerator generator;

  public EnumAdapterFactory(ResourceBundle bundle, EnumGenerator generator) {
    this.bundle = bundle;
    this.generator = generator;
  }

  @SuppressWarnings("unchecked")
  @Override
  public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    if (!Enum.class.isAssignableFrom(type.getRawType())) return null;

    return (TypeAdapter<T>) new GenericEnumTypeAdapter();
  }

  private final class GenericEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
    public T read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return generator.create(in.nextString());
    }

    public void write(JsonWriter out, T value) throws IOException {
      if(value == null) {
        out.nullValue();
        return;
      }
      out.value(bundle.getString("enum." 
            + value.getClass().getSimpleName() + "."
            + value.name()));
    }
  }
}

EnumGenerator的界面:

public interface EnumGenerator {
  <T extends Enum<T>> T create(String nextString);
}