定制球衣 Inflector

Custom jersey Inflector

我正在构建一个 RESTful 服务,其中应该根据资源文件描述生成端点。 使用隐式方法构建器处理程序注册资源工作得很好,但是当我尝试用显式替换隐式处理程序时,我遇到了麻烦。

在下面的示例中,我将隐式处理程序 Inflector 替换为显式 ItemInflector 实现。执行后需要字符串结果。

final Resource.Builder resourceBuilder = Resource.builder();
resourceBuilder.path("api/myservice/item");
final ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod("GET");

methodBuilder.produces(MediaType.TEXT_PLAIN_TYPE)
    .handledBy(new ItemInflector<ContainerRequestContext, String>(String.class));

final Resource resource = resourceBuilder.build();
registerResources(resource);

ItenInflector 实现:

public class ItemInflector<DATA extends ContainerRequestContext, RESULT> implements Inflector<DATA, RESULT> {

    private Class<RESULT> type;

    public ItemInflector(Class<RESULT> type) {
        this.type = type;
    }

    @Override
    public RESULT apply(DATA data) {
        return type.cast("Half programmatically generated endpoint");
    }
}

在运行时,当我尝试到达端点时抛出以下错误。

Caused by: java.lang.IllegalArgumentException: Type parameter RESULT not a class or parameterized type whose raw type is a class

有人可以弄清楚我在 Inflector 实现中做错了什么吗? 如何参数化或定义结果类型?

ItemInflector 实例创建期间指定的类型参数 (<ContainerRequestContext, String>) 在运行时丢失。原因是 Javas type erasure 行为。您必须在 subclass 中指定类型或在此处使用匿名 classes。

选项 1,匿名 class(是的,现在编译器保留了类型信息):

methodBuilder.produces(MediaType.TEXT_PLAIN_TYPE)
    .handledBy(new Inflector<ContainerRequestContext, String>(){
        ...
    });

选项2,在子类中指定类型:

public class ItemInflector implements Inflector<ContainerRequestContext, String> {
....
}

这里有一个关于类型擦除行为的非常详细的信息:Java generics - type erasure - when and what happens