我希望此参数映射到服务器端的枚举,如:
@POST @Path("/zoo") public Response createNewAnimal( @QueryParam("animal") @DefaultValue("CAT") AnimalType type ) throws Exception ... public enum AnimalType { BIG_BIRD,SMALL_CAT; }
但它不起作用!
在处理Web请求时,正在调用Enum.valueOf().当然它失败了,因为用户用作URL参数的鸟与Enum(AnimalType.BIG_BIRD)中的标识符不匹配.
没有办法覆盖valueOf()方法(它是静态的……),并且设置构造函数没有帮助(它是相反的逻辑方向).
所以也许你知道一个很好的解决方案,而不是只使用if … else …?
解决方法
public enum AnimalType { BIG_BIRD,SMALL_CAT,MEDIUM_DOG; }
然后,为了让JAX-RS知道要返回的实例,您的查询参数必须是?animal = BIG_BIRD,?animal = SMALL_CAT或?animal = MEDIUM_DOG.
查询参数的值被送到枚举的valueOf静态方法以获取实例.当然,如果你发送像鸟一样的东西它将无法匹配任何东西,它将无法正常工作,因为@QueryParam
期望这样:
The type T of the annotated parameter,field or property must either:
– Be a primitive type
– Have a constructor that accepts a single String argument
– Have a static method named valueOf that accepts a single String argument (see,for example,Integer.valueOf(String))
– Be List,Set or SortedSet,where T satisfies 2 or 3 above. The resulting collection is read-only.
这同样适用于@DefaultValue.您必须指定@DefaultValue(“BIG_BIRD”),@ DefaultValue(“SMALL_CAT”)或@DefaultValue(“MEDIUM_DOG”):
@POST @Path("/zoo") public Response createNewAnimal( @QueryParam("animal") @DefaultValue("SMALL_CAT") AnimalType type) { // ... return Response.ok().entity(type.toString()).build(); }
如果您不希望将Java类型的名称公开给客户端,则可以将正确的查询字符串值转换为枚举实例. if … else …如果是一种非常简单的方法来实现这一目标,但如果你想要更高档的东西,你可以创建一个这样的包装器:
import java.util.Collections; import java.util.HashMap; import java.util.Map; public class AnimalTypeWrapper { private static final Map<String,AnimalType> MAPPER = Collections .unmodifiableMap(new HashMap<String,AnimalType>() { { put("bird",AnimalType.BIG_BIRD); put("dog",AnimalType.MEDIUM_DOG); put("cat",AnimalType.SMALL_CAT); } }); private AnimalType type; public static AnimalTypeWrapper valueOf(String value) { AnimalType type = AnimalTypeWrapper.MAPPER.get(value.toLowerCase()); if (type == null) { // if nothing found just set the desired default value type = AnimalType.SMALL_CAT; } return new AnimalTypeWrapper(type); } private AnimalTypeWrapper(AnimalType type) { this.type = type; } public AnimalType getType() { return this.type; } }
并在您的资源方法中有:
@POST @Path("/zoo") public Response createNewAnimal( @QueryParam("animal") AnimalTypeWrapper typeWrapper) { // ... AnimalType type = typeWrapper.getType(); return Response.ok().entity(type.toString()).build(); }