我有一些使用以下方法的Jersey servlet:
@GET
@Path("/setState")
public String setState(@QueryParam("objId") int objId, @QueryParam("state") ObjectState state) {
/// bla bla bla ...
}
其中枚举ObjectState
定义为:
public enum ObjectState {
VISIBLE,
HIDDEN,
SELECTED,
SHADOWED
}
[当前,客户端要调用该方法,他们必须以字符串形式提及状态,例如&state=HIDDEN
。
我想让客户端传递序数枚举值,而不是包含其名称的字符串。例如,&state=2
表示该值为SELECTED
。
当前,我通过以下方法(不是很优雅)通过将参数类型更改为整数然后手动找到枚举值来手动完成:
public String setState(@QueryParam("objId") int objId, @QueryParam("state") int state) {
ObjectState stateAsEnumVal = stateAsEnumVal.values()[state];
// bla bla bla ...
}
是否可以自动优雅地进行选择?
对于@QueryParam
和其他@XxxParam
,如果它们遵循以下四个规则之一,则允许使用非原始类型(以及这些原始类型的列表):
valueOf(String)
方法。fromString(String)
方法。ParamConverter/ParamConverterProvider
。枚举可以直接使用的原因是,所有枚举都包含在返回类型的静态valueOf
方法中。但这没有用,因为它期望将枚举的字符串值作为参数。
尽管我们可以做的是添加静态fromString(String)
方法。 Jersey足够聪明,知道枚举中是否有fromString(String)
方法,应该尝试调用该方法而不是valueOf
方法。
所以您可以做类似的事情
public enum ObjectState {
VISIBLE,
HIDDEN,
SELECTED,
SHADOWED;
public static ObjectState fromString(String param) {
int value = Integer.parseInt(param);
return ObjectState.values()[value];
}
}
这应该有效。但是,唯一的问题是您失去了客户端发送字符串值的能力。
或者也许同时支持字符串和数字,您可以执行类似的操作
public static ObjectState fromString(String param) {
try {
int value = Integer.parseInt(param);
return ObjectState.values()[value];
} catch (NumberFormatException ex) {
return valueOf(param)
}
}
如果整数解析失败,您可以尝试使用默认的valueOf
。