我有一些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 ...
}
是否可以选择自动优雅地进行操作?
答案 0 :(得分:2)
使用@QueryParam
和其他@XxxParam
,如果它们遵循以下四条规则之一,则允许使用非原始(和那些原语的非列表)类型:
valueOf(String)
方法。fromString(String)
方法。ParamConverter/ParamConverterProvider
可以处理该类型。 enum开箱即用的原因是因为所有枚举都包含一个返回类型的静态valueOf
方法。但这没用,因为它期望枚举的字符串值作为参数。
我们可以做的是添加静态fromString(String)
方法。泽西很聪明,知道如果枚举中有fromString(String)
方法,那么应该尝试调用该方法而不是valueOf
方法。
所以你可以做点什么
public enum ObjectState {
VISIBLE,
HIDDEN,
SELECTED,
SHADOWED;
public static ObjectState fromString(String param) {
int value = Integer.parseInt(param);
switch(value) {
case 1: return ObjectState.VISIBLE;
case 2: return ObjectState.HIDDEN;
case 3: return ObjectState.SELECTED;
case 4: return ObjectState.SHADOWED;
default: throw new IllegalArgumentException();
}
}
}
这应该有效。但唯一的问题是你失去了客户端发送字符串值的能力。
或者也许支持字符串和数字,你可以做类似的事情
public static ObjectState fromString(String param) {
try {
int value = Integer.parseInt(param);
switch(value) {
case 1: return ObjectState.VISIBLE;
case 2: return ObjectState.HIDDEN;
case 3: return ObjectState.SELECTED;
case 4: return ObjectState.SHADOWED;
default: throw new IllegalArgumentException();
}
} catch (NumberFormatException ex) {
return valueOf(param)
}
}
如果整数解析失败,您可以尝试使用默认的valueOf
。