Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jakarta ee JavaEE拦截器更改返回类型_Jakarta Ee_Jax Rs - Fatal编程技术网

Jakarta ee JavaEE拦截器更改返回类型

Jakarta ee JavaEE拦截器更改返回类型,jakarta-ee,jax-rs,Jakarta Ee,Jax Rs,我希望我的JavaEE拦截器返回的类型不是JAX-RS服务方法中定义的类型,但是我收到一个ClassCastException。下面是一个简单的例子: package.com.example; @增加 @得到 @路径(“/me”) @产生(MediaType.APPLICATION_JSON) 公共用户me(){ 返回新用户(…); } @增加 @拦截器 公共类拦截器{ @阿隆登沃克 公共对象截获(InvocationContext ctx)引发异常{ runInNewResourceConte

我希望我的JavaEE拦截器返回的类型不是JAX-RS服务方法中定义的类型,但是我收到一个
ClassCastException
。下面是一个简单的例子:

package.com.example;
@增加
@得到
@路径(“/me”)
@产生(MediaType.APPLICATION_JSON)
公共用户me(){
返回新用户(…);
}
@增加
@拦截器
公共类拦截器{
@阿隆登沃克
公共对象截获(InvocationContext ctx)引发异常{
runInNewResourceContext(resourceContext->{
Object original=ctx.procedure();//是用户对象
返回MoreData(原始,resourceContext.getStats());
});//运行lambda后,上下文资源将被清理
}
}
java.lang.ClassCastException: com.example.MoreData不能为空 转换为com.example.User,位于 com.example.Service$Proxy$\u$\ uWeldSubclass.me(未知 来源)~[Service.class:?]at sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) ~[?:1.8.0_201]at invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 位于java.lang.reflect.Method.invoke(Method.java:498)的~[?:1.8.0201] ~[?:1.8.0_201]at 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$TypeOutingVoker.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:?]在

我猜这是因为我的JavaEE服务器是如何实现的:拦截器是从我的服务类的代理中调用的,代理需要返回在代理类中定义的类型

然而,从阅读JSR318拦截器规范可以看出,我不认为这是一个设计限制。我在规范中没有看到任何关于返回类型/值的信息,也没有提到“代理”这个词

JSR 318拦截器规范:

顺便说一句,我使用的是Payara 5.192(它使用的是Jersey 2.29),但我怀疑它是否相关

问题:

  • 我在说明书中遗漏了什么吗?或者是否有任何其他资源对此进行了记录

  • 其他JavaEE服务器是否以不同的方式实现拦截器


  • 我意识到我可以将
    me
    的返回类型更改为
    Object
    javax.ws.rs.core.Response
    ,或者我自己的泛型类型
    ReturnTypeHack
    (类型擦除应该使增强拦截器能够返回
    ReturnTypeHack
    ),但是我宁愿不要在服务中保留Java返回类型信息。

    一般,JSR-318拦截器,不能更改方法的返回类型。尽管我在规范中没有明确地找到这一点,但我非常确信这是由于Java语言的限制。例如,即使您说服拦截器机制返回不兼容的对象类型,被截获方法的调用方仍将获得
    ClassCastException

    从您展示的代码可以明显看出,您希望丰富JAX-RS方法的返回资源。使用另一种“拦截器”,即JAX-RS过滤器,这是绝对可行的。特别是对于您的情况,
    ContainerResponseFilter
    可以在调用resource方法后拦截调用。它可以使用
    ContainerResponseContext.getEntity()
    访问返回的实体,并使用
    ContainerResponseContext.setEntity(对象)
    替换为
    MoreData
    对象

    示例代码:

    @Provider
    @Augment
    public class AugmentFilter implements ContainerResponseFilter {
        @Override
        public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
            Object original = responseContext.getEntity();
            responseContext.setEntity(MoreData(original));
        }
    }
    

    看看规范,看看绑定注释是如何为JAX-RS工作的,您可能需要解决一些问题,但原则是正确的。

    谢谢,但是JAX-RS响应过滤器对我来说不起作用;我应该说明的。我给出的极其简化的示例代码并不表示拦截器需要处理对服务方法(ctx.procedure)本身的调用。