加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

如何使用基于JAX-RS的Restlet自动将@DefaultValue映射到枚举参数

发布时间:2020-12-15 02:51:05 所属栏目:Java 来源:网络整理
导读:我有一个Web API,用户可以(或可能不)传输URL参数,例如鸟,狗等. 我希望此参数映射到服务器端的枚举,如: @POST@Path("/zoo")public Response createNewAnimal( @QueryParam("animal") @DefaultValue("CAT") AnimalType type ) throws Exception ...public enu
我有一个Web API,用户可以(或可能不)传输URL参数,例如鸟,狗等.

我希望此参数映射到服务器端的枚举,如:

@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();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读