我正在构建一个 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 实现中做错了什么吗? 如何参数化或定义 RESULT 类型?
最佳答案
在 <ContainerRequestContext, String>
期间指定的类型参数 ( ItemInflector
)实例创建,在运行时丢失。原因是 Javas type erasure行为。您必须在子类中指定类型或在此处使用匿名类。
选项 1,匿名类(是的,现在编译器保留了类型信息):
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
关于java - 定制 Jersey Inflector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36159285/