65.9K
CodeProject 正在变化。 阅读更多。
Home

从 .NET 调用 Java/AXIS Web Service

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (6投票s)

2007年10月26日

CPOL

2分钟阅读

viewsIcon

69384

从基于 .NET 的客户端调用 Java/AXIS Web Service。使用 VS.NET 提供的自动 Web 引用添加可能会导致空 (null) 响应。

引言

好的,我为此挣扎了几个小时;谷歌搜索并没有帮上什么忙——除了在一些论坛中没有得到解答的类似问题的提问。 有时,当你从 .NET 客户端调用基于 AXIS 的 Web Service 时,你会收到一个 null (在 VB 中为 Nothing) 响应。 由于我完全不认为自己是第一个遇到这个问题的人,我认为这个解决方案至少会为处理这个问题的人提供一个良好的基础。

背景

问题所在:我的一个合作伙伴在他的机器上部署了一个基于 AXIS 的 Web Service。 由于我当时已经开始了我的 ASP.NET 2.0 项目,我试图从 VB.NET 调用他的模块。 虽然 Visual Studio 成功地读取了 WSDL 并构建了代理类,但我一直收到来自他的 Web 服务的 NULL 响应 (Nothing)。 然而,他的实现没有任何问题,因为其他类型的 Web 客户端运行顺畅(我甚至试用了这个漂亮的 通用 SOAP 客户端)。 奇怪的是,我没有从 .NET 收到任何异常,该服务似乎正常运行。 并且实际上确实如此。

所以,总而言之:下面的代码(通常是你期望 .NET 客户端调用 WS 的方式)返回了 null (在 VB 中为 Nothing)

'***Let's pretend that you have added a web reference
'   to a Java-enabled web service called Service1

'***The name of this web reference is AxisService

'***This service contains a web method called doMergeNames,
'   receiving two arguments, FName and SName, returning an XML string

Dim WS As New AxisService.Service1
Dim strFullNameXML as String
strFullNameXML=WS.doMergeNames("John","Doe")

嗯,strFullName 总是 Nothing。 没有抛出错误,只是一个空值。 对于 ASP .NET 1.1 和 2.0,行为完全相同。

使用代码

解决方案:在放置断点并重载一些方法以跟踪响应后,我发现该服务确实返回了正确的字符串,只是 .NET 很难读取它(也许是奇怪的字符?)。

因此,通过创建一个新类来继承自 Service1 并覆盖 GetWebResponse 函数来解决这个问题,以捕获完整的、正确的 SOAP 响应到我的一个变量中,然后手动解析 SOAP 信封。

这是代码

'I recommend you place this in a public module
' so that it is accessible from any part of your project

Imports System.Xml
Imports System.Net

Namespace AxisService
    '********that is a TERRIBLE HACK for accessing Java-Web services**************

    'for some STUPID reason all I got was null return values

    'I had to override the GetWebResponse and parse the SOAP return myself

    '*****************************************************************************

    Public Class myService1
        Inherits AxisService.Service1

        Private m_Return As String

        Public Property _ResultStr() As String
            Get
                Return m_Return
            End Get
            Set(ByVal value As String)
                'parse the soap string

                'something like the following

                '<?xml version="1.0" encoding="utf-8" ?> 

                '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

                '    <soapenv:Body>

                '        <dlwmin:doMergeNamesResponse xmlns:dlwmin="http://test.test.com/">

                '        <return>return string</return> 

                '        </dlwmin:ddoMergeNamesResponse>

                '    </soapenv:Body>

                '</soapenv:Envelope>


                Dim tmpXML As New XmlDocument
                tmpXML.LoadXml(value)

                Dim tmpValueNodeList As XmlNodeList
                Dim tmpValueNode As XmlNode

                tmpValueNodeList = _
                 tmpXML.DocumentElement.GetElementsByTagName("soapenv:Body")
                If tmpValueNodeList.Count > 0 Then
                    tmpValueNode = tmpValueNodeList.Item(0)
                End If
                If Not tmpValueNode Is Nothing Then
                    Me.m_Return = tmpValueNode.InnerText
                Else
                    Me.m_Return = ""
                End If

            End Set
        End Property


        Protected Overloads Overrides Function GetWebResponse(ByVal _
                            the_webRequest As WebRequest) As WebResponse
            Dim WR As WebResponse
            WR = MyBase.GetWebResponse(the_webRequest)

            Dim sr As New IO.StreamReader(WR.GetResponseStream)
            Me._ResultStr = sr.ReadToEnd
            Return MyBase.GetWebResponse(the_webRequest)
        End Function

    End Class

End Namespace

上面的代码将正确的字符串结果存储到 _ResultStr 属性中。 然而,由于你在将响应流返回到其余执行之前读取了它,将会抛出一个异常。 这是预期的;因此,为了调用此 Web Service,你将不得不引用新类,捕获异常,并获取 _ResultStr 属性,如下所示

Dim WS As New AxisService.myService1
Dim strFullNameXML as String

'trap the exception due to the stupid hack ***********

Try
  WS.doMergeNames("John","Doe")
Catch ex As Exception
 'do something here if you want to

'maybe check for the specific exception number, 
'I can't remember it :)

End Try

Dim strReturn As String = WS._ResultStr
'*****************************************************

关注点

我知道,这是一个糟糕的 hack,但它快速而肮脏 :)... 另外,我没有时间找出更优雅的解决方案。 也许,一个更简洁的解决方案是覆盖一些其他的 SOAP/.NET 内部函数,以便更正响应解析,而不是重叠它。

历史

  • 2007 年 10 月 26 日:首次代码提交。
© . All rights reserved.