在Python中,我可以轻松地使用Web服务:

from suds.client import Client
client = Client('http://www.example.org/MyService/wsdl/myservice.wsdl') #create client
result = client.service.myWSMethod("Bubi", 15)  #invoke method
print result    #print the result returned by the WS method

我想用Java达到这么简单的用法。

使用Axis或CXF,您必须创建一个Web服务客户端,即一个包复制所有Web服务方法的包,以便我们可以像使用普通方法一样调用它们。 我们称之为代理类 ; 通常它们是由wsdl2java工具生成的。

实用且用户友好。 但是每当我添加/修改Web服务方法并且我想在客户端程序中使用它时,我需要重新生成代理类

所以我找到了CXF DynamicClientFactory ,这种技术避免了使用代理类:

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
//...
//create client
DynamicClientFactory dcf = DynamicClientFactory.newInstance();
Client client = dcf.createClient("http://www.example.org/MyService/wsdl/myservice.wsdl");
//invoke method
Object[] res = client.invoke("myWSMethod", "Bubi");
//print the result
System.out.println("Response:\n" + res[0]);

但不幸的是,它创建并编译代理类运行时,因此在生产机器上需要JDK 我必须避免这种情况,或者至少我不能依赖它。

我的问题

是否有另一种方法可以在Java中以动态方式调用Web服务的任何方法,而无需在运行时使用JDK并且不生成“静态”代理类? 也许有一个不同的图书馆? 谢谢!

#1楼 票数:1

我知道这是一个非常古老的问题,但如果您仍然感兴趣,可以使用soap-ws github项目: https//github.com/reficio/soap-ws

这里有一个非常简单的示例用法:

Wsdl wsdl = Wsdl.parse("http://www.webservicex.net/CurrencyConvertor.asmx?WSDL");

SoapBuilder builder = wsdl.binding()
    .localPart("CurrencyConvertorSoap")
    .find();
SoapOperation operation = builder.operation()
    .soapAction("http://www.webserviceX.NET/ConversionRate")
    .find();
Request request = builder.buildInputMessage(operation)

SoapClient client = SoapClient.builder()
    .endpointUrl("http://www.webservicex.net/CurrencyConvertor.asmx")
    .build();
String response = client.post(request);

你可以看到它非常简单。

#2楼 票数:0

使用CXF 3.x,这可以通过StaxDataBinding实现 按照以下步骤获取基础知识。 当然,这可以根据您的需求进行增强。

  1. 创建StaxDataBinding,如下所示。 请注意下面的代码可以增强您的复杂程度。

     class StaxDataBinding extends AbstractInterceptorProvidingDataBinding { private XMLStreamDataReader xsrReader; private XMLStreamDataWriter xswWriter; public StaxDataBinding() { super(); this.xsrReader = new XMLStreamDataReader(); this.xswWriter = new XMLStreamDataWriter(); inInterceptors.add(new StaxInEndingInterceptor(Phase.POST_INVOKE)); inFaultInterceptors.add(new StaxInEndingInterceptor(Phase.POST_INVOKE)); inInterceptors.add(RemoveStaxInEndingInterceptor.INSTANCE); inFaultInterceptors.add(RemoveStaxInEndingInterceptor.INSTANCE); } static class RemoveStaxInEndingInterceptor extends AbstractPhaseInterceptor<Message> { static final RemoveStaxInEndingInterceptor INSTANCE = new RemoveStaxInEndingInterceptor(); public RemoveStaxInEndingInterceptor() { super(Phase.PRE_INVOKE); addBefore(StaxInEndingInterceptor.class.getName()); } public void handleMessage(Message message) throws Fault { message.getInterceptorChain().remove(StaxInEndingInterceptor.INSTANCE); } } public void initialize(Service service) { for (ServiceInfo serviceInfo : service.getServiceInfos()) { SchemaCollection schemaCollection = serviceInfo.getXmlSchemaCollection(); if (schemaCollection.getXmlSchemas().length > 1) { // Schemas are already populated. continue; } new ServiceModelVisitor(serviceInfo) { public void begin(MessagePartInfo part) { if (part.getTypeQName() != null || part.getElementQName() != null) { return; } part.setTypeQName(Constants.XSD_ANYTYPE); } }.walk(); } } @SuppressWarnings("unchecked") public <T> DataReader<T> createReader(Class<T> cls) { if (cls == XMLStreamReader.class) { return (DataReader<T>) xsrReader; } else { throw new UnsupportedOperationException( "The type " + cls.getName() + " is not supported."); } } public Class<?>[] getSupportedReaderFormats() { return new Class[] { XMLStreamReader.class }; } @SuppressWarnings("unchecked") public <T> DataWriter<T> createWriter(Class<T> cls) { if (cls == XMLStreamWriter.class) { return (DataWriter<T>) xswWriter; } else { throw new UnsupportedOperationException( "The type " + cls.getName() + " is not supported."); } } public Class<?>[] getSupportedWriterFormats() { return new Class[] { XMLStreamWriter.class, Node.class }; } public static class XMLStreamDataReader implements DataReader<XMLStreamReader> { public Object read(MessagePartInfo part, XMLStreamReader input) { return read(null, input, part.getTypeClass()); } public Object read(QName name, XMLStreamReader input, Class<?> type) { return input; } public Object read(XMLStreamReader reader) { return reader; } public void setSchema(Schema s) { } public void setAttachments(Collection<Attachment> attachments) { } public void setProperty(String prop, Object value) { } } public static class XMLStreamDataWriter implements DataWriter<XMLStreamWriter> { private static final Logger LOG = LogUtils .getL7dLogger(XMLStreamDataWriter.class); public void write(Object obj, MessagePartInfo part, XMLStreamWriter writer) { try { if (!doWrite(obj, writer)) { // WRITE YOUR LOGIC HOW you WANT TO HANDLE THE INPUT DATA //BELOW CODE JUST CALLS toString() METHOD if (part.isElement()) { QName element = part.getElementQName(); writer.writeStartElement(element.getNamespaceURI(), element.getLocalPart()); if (obj != null) { writer.writeCharacters(obj.toString()); } writer.writeEndElement(); } } } catch (XMLStreamException e) { throw new Fault("COULD_NOT_READ_XML_STREAM", LOG, e); } } public void write(Object obj, XMLStreamWriter writer) { try { if (!doWrite(obj, writer)) { throw new UnsupportedOperationException("Data types of " + obj.getClass() + " are not supported."); } } catch (XMLStreamException e) { throw new Fault("COULD_NOT_READ_XML_STREAM", LOG, e); } } private boolean doWrite(Object obj, XMLStreamWriter writer) throws XMLStreamException { if (obj instanceof XMLStreamReader) { XMLStreamReader xmlStreamReader = (XMLStreamReader) obj; StaxUtils.copy(xmlStreamReader, writer); xmlStreamReader.close(); return true; } else if (obj instanceof XMLStreamWriterCallback) { ((XMLStreamWriterCallback) obj).write(writer); return true; } return false; } public void setSchema(Schema s) { } public void setAttachments(Collection<Attachment> attachments) { } public void setProperty(String key, Object value) { } } } 
  2. 准备输入以匹配预期输入,如下所示

     private Object[] prepareInput(BindingOperationInfo operInfo, String[] paramNames, String[] paramValues) { List<Object> inputs = new ArrayList<Object>(); List<MessagePartInfo> parts = operInfo.getInput().getMessageParts(); if (parts != null && parts.size() > 0) { for (MessagePartInfo partInfo : parts) { QName element = partInfo.getElementQName(); String localPart = element.getLocalPart(); // whatever your input data you need to match data value for given element // below code assumes names are paramNames variable and value in paramValues for (int i = 0; i < paramNames.length; i++) { if (paramNames[i].equals(localPart)) { inputs.add(findParamValue(paramNames, paramValues, localPart)); } } } } return inputs.toArray(); } 
  3. 现在设置正确的数据绑定并传递数据

     Bus bus = CXFBusFactory.getThreadDefaultBus(); WSDLServiceFactory sf = new WSDLServiceFactory(bus, wsdl); sf.setAllowElementRefs(false); Service svc = sf.create(); Client client = new ClientImpl(bus, svc, null, SimpleEndpointImplFactory.getSingleton()); StaxDataBinding databinding = new StaxDataBinding(); svc.setDataBinding(databinding); bus.getFeatures().add(new StaxDataBindingFeature()); BindingOperationInfo operInfo = ...//find the operation you need (see below) Object[] inputs = prepareInput(operInfo, paramNames, paramValues); client.invoke("operationname", inputs); 
  4. 如果需要,您可以匹配以下操作名称

     private BindingOperationInfo findBindingOperation(Service service, String operationName) { for (ServiceInfo serviceInfo : service.getServiceInfos()) { Collection<BindingInfo> bindingInfos = serviceInfo.getBindings(); for (BindingInfo bindingInfo : bindingInfos) { Collection<BindingOperationInfo> operInfos = bindingInfo.getOperations(); for (BindingOperationInfo operInfo : operInfos) { if (operInfo.getName().getLocalPart().equals(operationName)) { if (operInfo.isUnwrappedCapable()) { return operInfo.getUnwrappedOperation(); } return operInfo; } } } } return null; } 

  ask by bluish translate from so

未解决问题?本站智能推荐:

1回复

CXFWeb服务客户端,如何处理来自调用的Web服务的响应?

我已经实现了一个Web服务客户端,该客户端在Web应用程序内部使用(使用Spring),并且此客户端收到CXF失败的响应并给我一条错误消息。 错误消息是: 服务器无法识别HTTP标头SOAPAction的值 我已经发现问题,但不知道该怎么做才能调整我的Web服务响应处理。 下面
1回复

调用Web服务时出现javax.xml.ws.soap.SOAPFaultException

我已经通过以下WSDL使用Apache CXF 2.x在eclipse中创建了一个Web服务客户端: https://test.timbrado.com.mx/cfdi/wstimbrado.asmx?WSDL 进行Web服务调用时,出现以下错误stacktrace(服务器无法处理请求-
2回复

为CXF服务生成客户端代码的最佳方法是什么?

我想为我的CXF服务生成一个客户端,所以我尝试了Axis 2代码生成器,但是它并没有生成直接使用的代码。 我期望有诸如client.getEmployeeByName("John Doe")类的东西,但是我必须创建请求类并在其上设置参数。 为CXF服务生成客户端代码的最佳方法是什么?
1回复

从端口的方法返回一个类而不是void

我是SOAP服务的初学者。 我有一个使用案例来使用一些SOAP方法。 因此,为此,我对客户端进行了编码以获取一些服务端口的方法数据。 当前,我从导入的WSDL中意识到,特定的服务方法具有void返回类型。 但是,我想要返回端口方法。 例如: 这是来自WSDL的当前行为: 但是
3回复

无法调用网络服务

我目前正在尝试使用由Apache CXF构建的客户端调用Web服务。 尽管该服务在浏览器中可用,但是由于以下错误,我无法连接到该服务。 关于这个问题有什么想法吗?
1回复

是否需要设置一个服务器运行时来在Eclipse中使用CXF生成Web服务客户端?

当我转到文件 - >新 - >其他 - > Web服务 - > Eclipse中的Web服务客户端并选择“Web服务运行时”时,我看到“Apache CFX 2.x”,但是完成按钮被禁用,我得到了在对话框中跟随: “从运行时和部署服务器列表中选择,或使用默认设置。”
1回复

Java客户端对Web服务(c#)的用户名和密码请求

我想使用apache cxf使客户端(java)请求Web服务。 网络服务: https://extenavigator.ukho.gov.uk/serviceB2B/submitUKHOOrdering.svc https://extenavigator.ukho.gov.uk/Se
1回复

检测Web服务中的客户端断开连接

我正在使用Apache CXF Web服务堆栈。 当客户端在操作完成之前超时或断开与服务器的连接时,服务器将继续运行该操作,直到完成为止。 我希望服务器检测客户端何时断开连接并相应地处理它。 有没有办法检测客户端何时使用Apache CXF断开连接? 那么使用其他Java Web服务堆