Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.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
Java 如何将不属于BindingProvider子类的对象显式转换为BindingProvider对象?_Java_Web Services_Jakarta Ee_Jax Ws_Soap Client - Fatal编程技术网

Java 如何将不属于BindingProvider子类的对象显式转换为BindingProvider对象?

Java 如何将不属于BindingProvider子类的对象显式转换为BindingProvider对象?,java,web-services,jakarta-ee,jax-ws,soap-client,Java,Web Services,Jakarta Ee,Jax Ws,Soap Client,我有一个web服务,其中我正在使用客户端API中的服务接口对象操作SOAP头 我需要将端口对象强制转换为BindingProvider对象。但我的端口对象并没有直接为该类创建子类。那么JVM怎么可能不抱怨呢 而且它也有效。ClassCastException没有运行时错误 代码段: public SearchDocument getSearchDocumentService(String wsdlUri, AuthBean auth){ SearchDocument_Servic

我有一个web服务,其中我正在使用客户端API中的服务接口对象操作SOAP头

我需要将端口对象强制转换为
BindingProvider
对象。但我的端口对象并没有直接为该类创建子类。那么JVM怎么可能不抱怨呢

而且它也有效。ClassCastException没有运行时错误

代码段:

    public SearchDocument getSearchDocumentService(String wsdlUri, AuthBean auth){
    SearchDocument_Service serv = null;
    serv = SearchDocument_Service.getServiceInstance(wsdlUri);
    SearchDocument searchDoc = serv.getSearchDocument();

    populateAuthAndHandlerInfo((BindingProvider)searchDoc, auth);//how is it that jvm doesn't complain here
    return searchDoc;
    }

    private void populateAuthAndHandlerInfo(BindingProvider port, AuthBean auth) {
    Binding binding = port.getBinding();
              List<Handler> handlerList = binding.getHandlerChain();
              handlerList.add(new EDMSSoapAuthHandler());
              binding.setHandlerChain(handlerList);
        Map<String, Object> context = port.getRequestContext();
        context.put("clientAuthInfo", auth);
        }

有几种方法可以回答你的问题

从高层次的角度来看 但我的端口对象并没有直接为该类创建子类。那么JVM怎么可能不抱怨呢

嗯<代码>搜索文档是一个界面。那么,当你打电话的时候

SearchDocument searchDoc = serv.getSearchDocument();
然后,
searchDoc
是实现接口的给定类型的实例,但是没有指定这个具体类是什么。它可以是任何东西,包括实现
SearchDocument
BindingProvider
的具体类,因为两者都是接口,任何给定类型都可以同时自由实现多个接口。 所以这里一定发生了这样的事情,对吧

来自JAX-WS规范 查看JAXWS规范可能会进一步启发您。您可以在下载,但我将在第4.2.3章为您引述一些要点:

代理在运行时提供对服务端点接口的访问,而无需静态生成stubclass。请参阅java.lang.reflect.Proxy 有关JDK支持的动态代理的更多信息

一致性(实现BindingProvider):代理实例必须实现javax-.xml.ws.BindingProvider

使用服务实例的getPort方法创建代理:T getPort(类sei)返回指定sei的代理

现在很容易把这些碎片重新组合起来

什么是
java.lang.reflect.Proxy
东西。 在JVM中,有一个用于创建代理对象的API<代码>代理对象(实例)是JVM中的一种特殊类型的beast,可以在运行时动态创建,并且可以使每个代理符合任何给定的接口。这就像在运行时而不是编译时创建一个
类,而不必编写java源文件。当然,有各种各样的限制,但也有许多可能性

一种是对JVM说:“嘿,给我一个
Proxy
对象,它同时实现接口
SearchDocument
BindingProvider
”。JVM也是如此。它返回一个对象,其具体类是
Proxy
(通常是Proxy$x,其中x是一个数字),并经过精心设计以实现这两个接口

如果您想知道这在这一点上是否有用,那么不,它不是,因为创建一个没有实现的类型是毫无意义的。但是有一种方法可以提供一种实现和行为,通过您编程的
InvocationHandler
(另一个讨论就是这样的)

因此,在这一点上,我们从规范中得到的是,如果我们在
javax.xml.ws.Service
上调用
getPort
,那么结果必须是一个JDK代理,它还必须实现
BindingProvider

回到你的案子上来
我敢打赌,这正是您调用时发生的情况:
SearchDocument\u服务
,它最终调用了一个
getPort
方法,并确保结果实现了
BindingProvider
,因为JAXWS说它必须这样做,而您的
SearchDocument
“业务”界面,因为这对你是有用的。

搞定了!!正如您所说,在
SearchDocument\u服务
impl类中调用了一个getPort()方法。我现在完全明白了。尽管所有这些都只是作为一个整体来处理有点复杂(代理>网络>服务端点>等等,等等,等等!)。谢谢GPI:)我会给这个是+1,一旦我得到一个代表15不是一个问题,我不介意我的代表这么多。也许你仍然可以接受这个答案。这很复杂,但是能够在接口之间屏蔽实现是非常聪明的(如果你想一想,WSDL端口类型就是一个接口,所以在我看来,JAXWS代理接口来放置序列化/XML和网络逻辑的方式是非常聪明的!)。
SearchDocument searchDoc = serv.getSearchDocument();