Uploaded image for project: 'Axis'
  1. Axis
  2. AXIS-1761

Deserialization of SOAP(document/literal) went wrong because of Introspection Problem

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Critical
    • Resolution: Unresolved
    • 1.2RC2
    • None
    • None
    • Windows XP, JDK 1.4.2_06

    Description

      Deserialization of SOAP(document/literal) went wrong because of Introspection Problem

      We use a WSDL in mode document/literal/wrapped with complex datastructures defined
      by XML schemata. If I send the SOAP request to the SOAP-Server we get a correct
      SOAP Response, but the Deserialization goes wrong. I have modified the BeanDeserializer
      with a work arround. More detailed information is explained later.

      If the logging is switched on the following stacktrace is thrown:

      12031 [main] ERROR org.apache.axis.client.Call - Exception:
      org.xml.sax.SAXException: Invalid element in de.d2vodafone.eai.legokias.soapgenerated.ResultDetailsObject - Status
      at org.apache.axis.encoding.ser.BeanDeserializer.onStartChild(BeanDeserializer.java:223)
      at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1031)
      at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
      at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1140)
      at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:238)
      at org.apache.axis.message.RPCElement.getParams(RPCElement.java:386)
      at org.apache.axis.client.Call.invoke(Call.java:2402)
      at org.apache.axis.client.Call.invoke(Call.java:2301)
      at org.apache.axis.client.Call.invoke(Call.java:1758)
      at de.d2vodafone.eai.legokias.soapgenerated.LegoKiasBindingStub.getCustomerBANDetails(LegoKiasBindingStub.java:6
      86)
      at de.d2vodafone.eai.legokias.LegoKiasFacade.getCustomerDetails(LegoKiasFacade.java:86)
      at de.d2vodafone.eai.legokias.test.GetCustomerBANTest.main(GetCustomerBANTest.java:35)

      The problem is the detection of getter/setter. The java.beans.Introspection class is used to fill the map with detailed type
      definition. The name of the PropertyDescription class is used as the key for these Map. I detected the following

      getStatus() -> status
      getBAN() -> BAN

      In the WSDL I defined them as Status and BAN. If now the BeanDeserializer tries to deserialize the data in the
      method "onStartChild()", it first tries to get detailed property definition. Because of the literal-Mode
      the propertyMap is used to get the information. The localName is used as the key for the map.
      In this special case the localName is "Status" but the entry in the map is registired as "status".
      The first letter is low sensitive. Hence an exception is thrown because with "Status" no entry
      in found.

      I implemented a work around, that isn't really good but it works:

      if (typeDesc != null)

      { // Lookup the name appropriately (assuming an unqualified // name for SOAP encoding, using the namespace otherwise) String fieldName = typeDesc.getFieldNameForElement(elemQName, isEncoded); propDesc = (BeanPropertyDescriptor)propertyMap.get(fieldName); fieldDesc = typeDesc.getFieldByName(fieldName); }

      if (propDesc == null) {
      // look for a field by this name.
      propDesc = (BeanPropertyDescriptor) propertyMap.get(localName);
      // *************************************************************
      // MY WORKARROUND
      // *************************************************************

      if(propDesc == null)

      { String k = localName.substring(0,1).toLowerCase() + localName.substring(1,localName.length()); propDesc = (BeanPropertyDescriptor) propertyMap.get(k); }

      }

      The follwing class shows the result of the Introspection class

      package de.d2vodafone.eai.legokias.test;

      import java.beans.IntrospectionException;
      import java.beans.Introspector;
      import java.beans.PropertyDescriptor;

      public class IntrospectionTest {
      private int status;
      private String BAN;

      public static void main(String[] args) {
      try {
      PropertyDescriptor[] props = Introspector.getBeanInfo(IntrospectionTest.class).getPropertyDescriptors();

      int len = props.length;

      for (int i=0; i < len; i++ )

      { System.out.println(props[i].getName()); }

      } catch (IntrospectionException e)

      { // TODO Auto-generated catch block e.printStackTrace(); }

      }
      public String getBAN()

      { return BAN; }

      public void setBAN(String ban)

      { BAN = ban; }

      public int getStatus()

      { return status; }

      public void setStatus(int status)

      { this.status = status; }

      }

      RESULT:

      BAN
      status

      I hope the my information helps you to fix the problem. I think my workarround costs tomuch time at runtime.

      With kind regards!

      Andre Genser

      Attachments

        1. eai-wsdl.zip
          14 kB
          Andre Genser
        2. BeanDeserializer.java
          21 kB
          Andre Genser

        Activity

          People

            Unassigned Unassigned
            agenser Andre Genser
            Votes:
            4 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated: