首先,提供一个接口,如果枚举未知,它将提供默认值。
public interface EnumWithDefault<E extends Enum<E>> {
E getDefault();
}
未来可能添加的 Enum 应实现此接口:
public enum MyEnum implements EnumWithDefault<MyEnum>{
ENUM_IN_VERSION_1, FUTURE;
public MyEnum getDefault(){ return FUTURE; }
}
注册一个 TranslatorFactory ,如果实现将提供默认值:
return new ValueTranslator<Enum<?>, String>(path, String.class) {
@Override
public Enum<?> loadValue(String value, LoadContext ctx) {
try{
return Enum.valueOf((Class<Enum>)type, value.toString());
}catch(Exception e){
if (EnumWithDefault.class.isAssignableFrom(enumType)) {
EnumWithDefault<E> any = (EnumWithDefault<E>) enumType.getEnumConstants()[0];
result = any.getDefault();
}else{
throw e;
}
}
}
使用新枚举部署的版本 2:
public enum MyEnum implements EnumWithDefault<MyEnum>{
ENUM_IN_VERSION_1, ENUM_IN_VERSION_2, FUTURE;
public MyEnum getDefault(){ return FUTURE; }
}
当应用程序的版本 2 被部署并且 ENUM_IN_VERSION_2 存储在与某些实体相关的数据存储中时,在访问两个版本的端点时响应会有所不同。
点击第一个版本返回值 FUTURE 允许客户端显示适当的消息:
http://1.myapi.appspot.com/entities
返回:
<myEntity id='xyz' category='FUTURE' />
命中版本 2 提供了新的枚举:
http://2.myapi.appspot.com/entities
返回:
<myEntity id='xyz' category='ENUM_IN_VERSION_2' />
此解决方案允许在以后的版本中添加和使用额外的枚举,而旧版本根据合同向客户提供“未来”可能的价值。