【发布时间】:2019-07-01 20:08:48
【问题描述】:
我希望我的 Java EE 拦截器返回与 JAX-RS 服务方法中定义的类型不同的类型,但我收到了 ClassCastException。这是一个最小的例子:
package com.example;
@Augment
@GET
@Path("/me")
@Produces(MediaType.APPLICATION_JSON)
public User me() {
return new User(...);
}
@Augment
@Interceptor
public class AugmentInterceptor {
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
runInNewResourceContext(resourceContext -> {
Object original = ctx.proceed(); // is a User object
return MoreData(original, resourceContext.getStats());
}); // context resources are cleaned-up after the lambda runs
}
}
java.lang.ClassCastException: com.example.MoreData 不能 转换为 com.example.User 在 com.example.Service$Proxy$_$$_WeldSubclass.me(未知 来源)~[Service.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) ~[?:1.8.0_201] 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201] 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201] 在 java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201] 在 org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80) ~[jersey-server.jar:?] 在 org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:253) [jersey-server.jar:?] 在 org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) [jersey-common.jar:?] 在
我猜这是因为我的 Java EE 服务器是如何实现的:拦截器是从我的服务类的代理中调用的,并且代理需要返回代理类中定义的类型。
但是,从阅读 JSR 318 拦截器规范中可以看出,我认为这不是设计限制。我在规范中没有看到任何关于返回类型/值的信息,也没有提到“代理”这个词。
JSR 318 拦截器规范:
https://jcp.org/en/jsr/detail?id=318
https://download.oracle.com/otndocs/jcp/interceptors-1_2A-mrel3-spec/
顺便说一句,我使用的是 Payara 5.192(它使用 Jersey 2.29),但我怀疑它是否相关。
问题:
我是否遗漏了规范中的某些内容?或者是否有任何其他资源记录在案?
其他 Java EE 服务器是否以不同的方式实现拦截器?
【问题讨论】:
标签: jakarta-ee jax-rs