Java 在VisualStudio2008中使用Axis2 Web服务
让VisualStudio很好地使用Axis2 web服务有点困难。这个问题很奇怪,虽然不是一个表演的障碍。如果有什么让人讨厌的话,我真的很感激能有办法解决这个问题 问题在于,在C#代码中使用web服务时,所有参数或返回值都不在其本机数据类型中。因此,与其只是能够打电话,例如:Java 在VisualStudio2008中使用Axis2 Web服务,java,.net,visual-studio,web-services,axis2,Java,.net,Visual Studio,Web Services,Axis2,让VisualStudio很好地使用Axis2 web服务有点困难。这个问题很奇怪,虽然不是一个表演的障碍。如果有什么让人讨厌的话,我真的很感激能有办法解决这个问题 问题在于,在C#代码中使用web服务时,所有参数或返回值都不在其本机数据类型中。因此,与其只是能够打电话,例如: string timeDiff = MyWebService.GetServerTimeDifference(LocalTime) Console.WriteLine(timeDiff); 我得写信 MyWebServ
string timeDiff = MyWebService.GetServerTimeDifference(LocalTime)
Console.WriteLine(timeDiff);
我得写信
MyWebService.GetServerTimeDifference request = new MyWebService.GetServerTimeDifference();
request.@LocalTime = LocalTime;
Console.WriteLine(MyWebService.GetServerTimeDifference(request).@return);
正如你所知道的,这很快就会变得很烦人。奇怪的是,当创建对Web服务的Web引用时,所有数据类型和参数都正确地显示在服务发现页面中。我曾尝试修改web服务的WSDL文件,以删除可能会使visual studio感到困惑的任何内容,但到目前为止,我还未能使其正常工作
我在某处读到,这是反序列化过程中的Visual Studio和/或.Net问题,而不是web服务本身的问题。我认为这可能是真的,因为web服务可以在NetBeans中正确使用
Web服务是用Java编写的,托管在axis2/Tomcat服务器上,但客户端软件将用C#.Net 2.0编写
不管怎样,以前有人经历过这种情况吗?我一直无法找到我再次阅读有关反序列化问题的页面,因此如果有人有任何可以帮助我解决问题的话,我将非常感谢
我在某个地方读到这是一种视觉效果
中的Studio和/或.Net问题
反序列化过程,而不是
web服务本身存在问题。
我想这可能是真的,因为
可以正确使用web服务
在NetBeans中
我以前遇到过这个问题-这是一个.Net问题。我的方法是用大锤将ant原封不动地敲下来,然后在.Net中重新编写服务
我在某个地方读到这是一种视觉效果
中的Studio和/或.Net问题
反序列化过程,而不是
web服务本身存在问题。
我想这可能是真的,因为
可以正确使用web服务
在NetBeans中
我以前遇到过这个问题-这是一个.Net问题。我的方法是对ant使用一把大锤,然后在.Net中重新编写服务。我建议您使用文档/文字/包装的样式定义WSDL,据我所知,在需要互操作性时,这似乎是最合适的 这使您的服务实现在WCF中表现良好,而Visummer Studio 2008在定义服务引用时使用WCF 可以在不破坏现有实现的情况下修改服务的WSDL规范,但不要指望它 然而,棘手的部分是,您必须在WSDL中使用一些特殊的术语,以便WCF不会突然按照您的要求生成漂亮的包装。在您的例子中,自动生成的客户机代码似乎回到了文档/文字样式,在这里您创建并初始化“structs”,并将其提供给您的客户机服务方法 本质上,您需要做的是:
<wsdl:definitions
targetNamespace="http://tempuri.org"
xmlns:tns="http://tempuri.org"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema
elementFormDefault="qualified"
targetNamespace="http://tempuri.org"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Wrapper elements. Conventions apply to wrapper element names! -->
<xsd:element name="GetVersionInformation" nillable="true" type="tns:VoidType" />
<xsd:element name="GetVersionInformationResponse" nillable="true" type="tns:VersionInformationType" />
<!-- Just a void type -->
<xsd:complexType name="VoidType">
<xsd:sequence />
</xsd:complexType>
<!-- Major and minor version information -->
<xsd:complexType name="VersionInformationType">
<xsd:sequence>
<xsd:element nillable="true" minOccurs="1" maxOccurs="1" name="version" type="xsd:NMTOKEN" />
<xsd:element minOccurs="1" maxOccurs="1" name="major" type="xsd:int" />
<xsd:element minOccurs="1" maxOccurs="1" name="minor" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<!-- GetVersionInformation -->
<wsdl:message name="GetVersionInformationSoapIn">
<wsdl:part name="parameters" element="tns:GetVersionInformation" />
</wsdl:message>
<wsdl:message name="GetVersionInformationSoapOut">
<wsdl:part name="parameters" element="tns:GetVersionInformationResponse" />
</wsdl:message>
<!-- Port type -->
<wsdl:portType name="MyServicePortType">
<wsdl:operation name="GetVersionInformation">
<wsdl:input message="tns:GetVersionInformationSoapIn" />
<wsdl:output message="tns:GetVersionInformationSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyServiceSOAP11Binding" type="tns:MyServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="GetVersionInformation">
<wsdl:input>
<soap:body use="literal" parts="parameters" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="MyServiceSOAP12Binding" type="tns:MyServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="GetVersionInformation">
<wsdl:input>
<soap12:body use="literal" parts="parameters" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MyService">
<wsdl:port name="MyServiceSOAP11port" binding="tns:MyServiceSOAP11Binding">
<soap:address location="http://localhost:80/mojo/services/MyService" />
</wsdl:port>
<wsdl:port name="MyServiceSOAP12port" binding="tns:MyServiceSOAP12Binding">
<soap12:address location="http://localhost:80/mojo/services/MyService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
此外,从C#调用此代码如下:
// The endpointConfigurationName must match the corresponding entry
// in app.config, with the following content:
//
// <configuration>
// <system.serviceModel>
// <bindings>
// <basicHttpBinding>
// <binding name="MyServiceSOAP11Binding" ...>
// </binding>
// .../...
// </basicHttpBinding>
// </bindings>
// <client>
// <endpoint
/// ... binding="basicHttpBinding"
// ... bindingConfiguration="MyServiceSOAP11Binding"
// ... name="MyServiceSOAP11port" />
// </client>
// </system.serviceModel>
// </configuration>
//
string endpointConfigurationName = "MyServiceSOAP11port";
string wsEndpoint = "http://localhost/mojo/services/MyService";
MyService.MyServicePortTypeClient wsClient = null;
try
{
wsClient = new MyService.MyServicePortTypeClient(endpointConfigurationName, wsEndpoint);
}
catch (InvalidOperationException ioe)
{
// Possibly a problem with the configuration
// Inform(Logging.LogLevel.WARNING, "Potential problem with configuration: " + ioe.Message);
return;
}
string wsUsername = "John";
string wsPassword = "Doe";
if (!String.IsNullOrEmpty(wsUsername) && !String.IsNullOrEmpty(wsPassword))
{
UserNamePasswordClientCredential credentials = wsClient.ClientCredentials.UserName;
credentials.UserName = wsUsername;
credentials.Password = wsPassword;
}
try
{
int major;
int minor;
string version = wsClient.GetVersionInformation(out major, out minor);
// Inform(Logging.LogLevel.DEBUG, "Service has version " + version);
}
catch (System.ServiceModel.EndpointNotFoundException enfe)
{
// string info = "Could not contact MyService: " + enfe.Message;
// Inform(Logging.LogLevel.ERROR, info);
return;
}
catch (System.ServiceModel.FaultException fe)
{
// string info = "Could not contact MyService: " + fe.Message;
// Inform(Logging.LogLevel.ERROR, info);
return;
}
Axis2和Axiom非常适合使用。如果您在生成C#客户机时遇到问题,请重新访问您的WSDL—Axis2不太可能存在问题。顺便说一句,我们在服务配置中提到的“地址”模块通常是默认添加的,但也有其他模块可用于处理WS-I标准的其他部分。我建议您使用文档/文字/包装的样式定义WSDL,据我所知,当您需要互操作性时,它似乎是最合适的 这使您的服务实现在WCF中表现良好,而Visummer Studio 2008在定义服务引用时使用WCF 可以在不破坏现有实现的情况下修改服务的WSDL规范,但不要指望它 然而,棘手的部分是,您必须在WSDL中使用一些特殊的术语,以便WCF不会突然按照您的要求生成漂亮的包装。在您的例子中,自动生成的客户机代码似乎回到了文档/文字样式,在这里您创建并初始化“structs”,并将其提供给您的客户机服务方法 本质上,你需要什么
// The endpointConfigurationName must match the corresponding entry
// in app.config, with the following content:
//
// <configuration>
// <system.serviceModel>
// <bindings>
// <basicHttpBinding>
// <binding name="MyServiceSOAP11Binding" ...>
// </binding>
// .../...
// </basicHttpBinding>
// </bindings>
// <client>
// <endpoint
/// ... binding="basicHttpBinding"
// ... bindingConfiguration="MyServiceSOAP11Binding"
// ... name="MyServiceSOAP11port" />
// </client>
// </system.serviceModel>
// </configuration>
//
string endpointConfigurationName = "MyServiceSOAP11port";
string wsEndpoint = "http://localhost/mojo/services/MyService";
MyService.MyServicePortTypeClient wsClient = null;
try
{
wsClient = new MyService.MyServicePortTypeClient(endpointConfigurationName, wsEndpoint);
}
catch (InvalidOperationException ioe)
{
// Possibly a problem with the configuration
// Inform(Logging.LogLevel.WARNING, "Potential problem with configuration: " + ioe.Message);
return;
}
string wsUsername = "John";
string wsPassword = "Doe";
if (!String.IsNullOrEmpty(wsUsername) && !String.IsNullOrEmpty(wsPassword))
{
UserNamePasswordClientCredential credentials = wsClient.ClientCredentials.UserName;
credentials.UserName = wsUsername;
credentials.Password = wsPassword;
}
try
{
int major;
int minor;
string version = wsClient.GetVersionInformation(out major, out minor);
// Inform(Logging.LogLevel.DEBUG, "Service has version " + version);
}
catch (System.ServiceModel.EndpointNotFoundException enfe)
{
// string info = "Could not contact MyService: " + enfe.Message;
// Inform(Logging.LogLevel.ERROR, info);
return;
}
catch (System.ServiceModel.FaultException fe)
{
// string info = "Could not contact MyService: " + fe.Message;
// Inform(Logging.LogLevel.ERROR, info);
return;
}
<serviceGroup name="MyServices">
<service name="MyService" scope="application">
<description>My Service - document/literal wrapped style, suited for .NET integration</description>
<!-- Service methods -->
<operation name="GetVersionInformation">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
<actionMapping>http://tempuri.org/MyServicePortType/GetVersionInformationRequest</actionMapping>
</operation>
<!-- Use WS-Adressing, ... -->
<module ref="addressing" />
<!-- Service implementation -->
<parameter name="ServiceClass">com.mycompany.services.MyService</parameter>
</service>
<service name="MyOtherService" scope="application" >
.../...
</service>
</serviceGroup>
package com.mycompany.services.MyService;
import javax.xml.stream.XMLStreamException;
import javax.xml.namespace.QName;
import org.apache.axiom.om.*;
import org.apache.axis2.context.ServiceContext;
import org.apache.log4j.Logger;
public class MyService {
public static final Integer MAJOR_VERSION = 1;
public static final Integer MINOR_VERSION = 0;
public static final String NAMESPACE = "http://tempuri.org";
public static final String NAMESPACE_ALIAS = "tns";
public static final String GET_VERSION_INFORMATION_RESPONSE_ELEMENT_NAME = "GetVersionInformationResponse";
private ServiceContext serviceContext = null;
private String serviceName = null;
private static final Logger log = Logger.getLogger("SERVICE");
public void init(ServiceContext serviceContext) throws Exception {
this.serviceContext = serviceContext;
serviceName = serviceContext.getName();
}
public OMElement GetVersionInformation(OMElement element) throws XMLStreamException {
// --- Handle request ---
String version = "" + MAJOR_VERSION + "." + MINOR_VERSION;
if (log.isDebugEnabled()) {
log.debug("Retrieving version information: " + version);
}
// --- Prepare response ---
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace omNs = factory.createOMNamespace(NAMESPACE, NAMESPACE_ALIAS);
//
OMElement response = factory.createOMElement(GET_VERSION_INFORMATION_RESPONSE_ELEMENT_NAME, omNs);
{
OMElement value;
{
value = factory.createOMElement("version", omNs);
value.addChild(factory.createOMText(value, version));
response.addChild(value);
}
{
value = factory.createOMElement("major", omNs);
value.addChild(factory.createOMText(value, "" + MAJOR_VERSION));
response.addChild(value);
}
{
value = factory.createOMElement("minor", omNs);
value.addChild(factory.createOMText(value, "" + MINOR_VERSION));
response.addChild(value);
}
}
return response;
}
}