knk*_*knk 2 java web-services jax-ws soap-client jakarta-ee
我有一个 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);
}
Run Code Online (Sandbox Code Playgroud)
搜索文档.java:
@WebService(name = "SearchDocument", targetNamespace = "http://services.abc.com/Technology/SearchDocument/service/v1")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
ObjectFactory.class
})
public interface SearchDocument {
/**
*
* @param body
* @return
* returns com.abc.technology.search.document.client.v1.SearchOnMetadataResponse
* @throws AbcServiceException
* @throws AbcInvalidMessageException
* @throws AbcProducerApplicationException
*/
@WebMethod(action = "http://services.abc.com/Technology/SearchDocument/service/v1/soap11/SearchDocument/searchOnMetadata")
@WebResult(name = "SearchOnMetadataResponse", targetNamespace = "http://services.abc.com/Technology/SearchDocument/contract/v1", partName = "body")
public SearchOnMetadataResponse searchOnMetadata(
@WebParam(name = "SearchOnMetadata", targetNamespace = "http://services.abc.com/Technology/SearchDocument/contract/v1", partName = "body")
SearchOnMetadataRequest body)
throws AbcInvalidMessageException, AbcProducerApplicationException, AbcServiceException
;
}
Run Code Online (Sandbox Code Playgroud)
有几种方法可以回答您的问题。
但是我的端口对象没有直接继承那个类。那么JVM怎么可能不抱怨呢?
嗯...SearchDocument是一个接口。所以,当你打电话
SearchDocument searchDoc = serv.getSearchDocument();
Run Code Online (Sandbox Code Playgroud)
然后searchDoc是实现接口的给定类型的实例,但没有指定这个具体类是什么。它可以是任何东西,包括同时实现SearchDocument和的具体类BindingProvider,因为两者都是接口,任何给定的类型都可以同时实现多个接口。所以这一定是这里发生的事情,对吧?
查看 JAXWS 规范可能会进一步启发您。您可以在https://jcp.org/en/jsr/detail?id=224下载它,但我会在第 4.2.3 章为您引用一些要点:
代理在运行时提供对服务端点接口的访问,而无需静态生成存根类。有关 JDK 支持的动态代理的更多信息,请参阅 java.lang.reflect.Proxy
...
一致性(实现 BindingProvider):代理的实例必须实现 javax-.xml.ws.BindingProvider
...
使用Service 实例的 getPort 方法创建代理: T getPort(Class sei) 返回指定 SEI 的代理
现在很容易将这些部分重新组合在一起。
java.lang.reflect.Proxy东西。在 JVM 中,有一个用于创建代理对象的 API。Proxy对象(实例)是 JVM 中一种特殊的野兽,可以在运行时动态创建,并且可以使每个代理符合任何给定的接口。这就像Class在运行时创建一个,而不是在编译时,并且不必编写它的 java 源文件。当然,有各种限制,但也有很多可能性。
一个是说给JVM:“哎,给我一个Proxy对象,它实现的接口SearchDocument,并BindingProvider在同一时间”。JVM 也是如此。它返回一个对象,它的具体类是Proxy(通常是 Proxy$x,其中 x 是一个数字),并且是专门为实现这两个接口而设计的。
如果你想知道这在这一点上是否有任何用处,那么不,它不是,因为创建一个没有实现的类型是毫无意义的。但是有一种方法可以通过所谓的InvocationHandler你编程的方式来提供实现和行为(具体如何是另一个讨论)。
所以,在这一点上,我们从规范得到的是,如果我们所说getPort的一个javax.xml.ws.Service,然后,其结果必然是一个JDK代理,那也必须实现BindingProvider。
我敢打赌,这正是您调用 : 时发生的情况SearchDocument_Service,它最终调用一个getPort方法,并确保结果实现BindingProvider,因为 JAXWS 说它必须这样做,以及您的SearchDocument“业务”接口,因为它对你。
| 归档时间: |
|
| 查看次数: |
1464 次 |
| 最近记录: |