调用java的webservice返回null

When you try invoke a Java/Axis Web Service from a proxy class generated by Visual Studio 2005 or Visual Studio 2008 you often crash against the ‘return null’ issue.

The web service seems to get called correctly and it responds to your client in the right way (you have no exception of any sort), but your returned object is null, it happened to me to face this situation today for the first time, there are a couple of things you can do to debug and resolve this situation:

  • Let’s consider our function call:
       1: [Test]
       2: public void T1()
       3: {
       4:     Test.TestWs ws = new
    AxisWebService.Test.TestWs ();
       5:     Test.State[] arr =
    ws.getStates(1);
       6:     Assert.IsNotNull(arr);
       7: }

here we expect to have back an array of State objects,
instead we obtain the hated ‘null’.

  • The
    first thing to do is to download and install ‘Fiddler’ (do it right now if
    you don’t have it already) and have a look at what the web service respond
    to us (the snippet is a trimmed response):
       1: HTTP/1.1 200
    OK
       2: Connection: close
       3: Date: Wed, 15 Oct 2008
    12:36:26 GMT
       4: Server:
    Microsoft-IIS/6.0
       5: X-Powered-By:
    ASP.NET
       6: Content-Type:
    text/xml;charset=utf-8
       7: 
       8: <?xml
    version="1.0" encoding="utf-8"?>
       9: <soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      10: <soapenv:Body>
      11: <getStatesResponse
    xmlns="">
      12: <item
    xsi:type="ns1:State"
    xmlns:ns1="http://mynamespace.it/">
      13:
    <Code>A001</Code>
      14:
    <Description>Test</Description>
      15: </item>
      16:
    </getStatesResponse>
      17:
    </soapenv:Body>
      18: </soapenv:Envelope>

Since the web service is responding correctly the
problem is in the deserialization stage of the data stream sent back by the web
service.

  • It’s time to
    show some hidden file of the solution and look inside the ‘reference.cs’
    (this is the default file in which Visual Studio creates some proxy
    classes).

Looking at the proxy classes generated by Visual
Studio, it seems that we have all that we need: a class to call the web service
and series of classes that map the objects the service returns; where’s the
problem then? it turns out that the web service client can’t understand the
response stream, so the problem is in a mismatch somewhere.

Given the fact we have all the classes and
all of them have the right properties, it’s time to look for the namespaces:

  • Visual
    Studio 2005
       1:
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://mynamespace.it/getStates",
       2:     Use = System.Web.Services.Description.SoapBindingUse.Literal,
       3:     ParameterStyle =
    System.Web.Services.Protocols.SoapParameterStyle.Bare)]
       4: [return:
    System.Xml.Serialization.XmlArrayAttribute("getStatesResponse",
    Namespace = "http://mynamespace.it/")]
       5: [return:
    System.Xml.Serialization.XmlArrayItemAttribute("item", Form =
    System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
       6: public Stato[]
    getStates([System.Xml.Serialization.XmlElementAttribute(Namespace = "http://mynamespace.it/")]
    int getStatesRequest)
       7: {
       8:     object[] results =
    this.Invoke("getStates", new object[] {
       9:                 getStatesRequest});
      10:     return ((State[])(results[0]));
      11: }

pay attention to line number 4:

1: [return:
System.Xml.Serialization.XmlArrayAttribute("getStatesResponse",
Namespace = "http://mynamespace.it/")]

here it states that the getResponseState element is
qualified with the ‘http://mynamespace.it'/’ namespace...but look at what Fiddler captured for us
(line 11 of the previous snippet): there we see that the namespace associated
with the element is “” (empty string), so here it is our mismatch. To fix the
problem you have to manually edit the attribute and correct the namespace to “”
(empty string).

Be very careful: writing Namespace =
“” or removing it at all are two completely different things.

Having made this fix our test passes and we are able
to get our objects back from the web service.

  • Visual
    Studio 2008 
    It produces a completely different set of classes to
    call the web service, we have an interface that describes the service, a
    series of classes that represent the request and response of each method
    exposed by the interface and finally we have the proxy classes for the
    objects returned. We know that the problem is at the ‘client’ side so
    checking the request classes is useless, we focus our attention on the
    response classes and on object classes to verify the namespace
    mappings:
       1:
    [System.Diagnostics.DebuggerStepThroughAttribute()]
       2:
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
    "3.0.0.0")]
       3:
    [System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
       4: public partial class
    getStatesResponse {
       5:    
       6:    
    [System.ServiceModel.MessageBodyMemberAttribute(Name="getStatesResponse",
    Namespace="http://mynamespace.it/", Order=0)]
       7:    
    [System.Xml.Serialization.XmlArrayItemAttribute("item",
    Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
       8:     public State[]
    getStatesResponse1;
       9:    
      10:     public getStatesResponse() {
      11:     }
      12:    
      13:     public getStatesResponse(State[]
    getStatesResponse1) {
      14:         this.getStatesResponse1 =
    getStatesResponse1;
      15:     }
      16: }

look at line 6, you can see a namespace mismatch
again, the fix is the same applied before.

In the end, if you are using a
Java/Axis Web Service and you get null results from you service calls, don't
trust the auto-generated proxy classes too much and check that the attribute
that defines the namespace for each object match what you get from the wsdl and
from the traced response.

引用地址:<http://www.primordialcode.com/blog/post/invoking-javaaxis-web-service-net-return-null-issue

上一篇:UIKit和Core Graphics绘图(三)——绘制虚线,椭圆以及饼图


下一篇:Word文献类型标志