could not find deserializer for type : Error

2020-02-14 08:06发布

问题:

I have to make a SOAP call from my java program ,for which I used apache axis. My program is as follows :

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.rpc.ParameterMode;
import javax.xml.namespace.QName;
public class Project {
   public static void main(String [] args) {

   try {

       String endpoint ="http://RequestUrl";
       Service  service = new Service();
       Call call = (Call) service.createCall();
       call.setTargetEndpointAddress( new java.net.URL(endpoint) );
       call.setOperationName(new QName(endpoint, "getFrsFileData"));
       String value = (String) call.invoke(new Object[] { "24BB7","frs1001" } );
       System.out.println(value);
       }

    catch (Exception e) {
       System.err.println(e.toString());
       }

    }
   }

This on execution gives an error as follows

  • Exception: org.xml.sax.SAXException: Deserializing parameter 'getFrsFileDataReturn': could not find deserializer for type {http://Url}FrsFileSoapDO at org.apache.axis.message.RPCHandler.onStartChild(RPCHandler.java:277) at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035) at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165) at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141) at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:345) at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384) at org.apache.axis.client.Call.invoke(Call.java:2467) at org.apache.axis.client.Call.invoke(Call.java:2366) at org.apache.axis.client.Call.invoke(Call.java:1812) at Project.main(Project.java:33) org.xml.sax.SAXException: Deserializing parameter 'getFrsFileDataReturn': could not find deserializer for type {http://Url}FrsFileSoapDO

Tried the same call using SOAPUI , but it did not help me debug this .

Please help me out in debugging this java code,

Thank You

回答1:

I got help from my friend and was able to arrive at the answer . The problem is that the soap call , gives a soap response which comes as a bean of type "FrsFileSoapDO" . As I have not given anything in code of how my program will understand the received bean , that gave me an error saying "could not find deserializer for type {http://Url}FrsFileSoapDO" . Now the step's to clear the problem is

1) create a "QName" to say what is the namespace that "FrsFileSoapDO" refers to .

2) create Bean serializer (that knows how to serialize the bean),

3) create a Bean deserializer (that knows how to deserialize the bean) ,

4) Do the mapping saying that the QName q maps to the class FrsFileSoapDO.class (before that make sure that you have the FrsFileSoapDO.class with you and you have imported it )

Now lets implement this in the program , (I am repeating only the try block here)

try {

   String endpoint ="http://RequestUrl";
   Service  service = new Service();
   Call call = (Call) service.createCall();
   call.setTargetEndpointAddress( new java.net.URL(endpoint) );

   QName q = new QName ("http://Url", "FrsFileSoapDO"); // step 1
   BeanSerializerFactory bsf =   new BeanSerializerFactory(FrsFileSoapDO.class,q);   // step 2
   BeanDeserializerFactory bdf = new BeanDeserializerFactory(FrsFileSoapDO.class,q);  // step 3
   call.registerTypeMapping(FrsFileSoapDO.class,q, bsf, bdf); //step 4

   call.setOperationName(new QName(endpoint, "getFrsFileData"));
   FrsFileSoapDO s = (FrsFileSoapDO) call.invoke(new Object[] { "24BB7","frs1001" } );  
   System.out.println(s.getFilename());  
   }

This works giving me the expected output.

The document for the functions Call,BeanSerializerFactory,BeanDeserializerFactory are available at BeanSerializerFactory and BeanDeserializerFactory



回答2:

I was facing same problem. The only mistake I think in your code is below line:

call.setOperationName(new QName(endpoint, "getFrsFileData"));

You should not use endpoint for QName constructor parameter. Either you can leave it empty if you are only sending string params but in case some complex data you should provide the mapping here from the wsdl file. Check parameters in wsdl file for this web service method and give the same mapping here. For example for me it was a file transfer so the entry in wsdl was:

<wsdl:message name="sendFileRequest">
  <wsdl:part name="in0" type="apachesoap:DataHandler"/>
  <wsdl:part name="in1" type="soapenc:string"/>
</wsdl:message>

and in the client code you have give same type like:

call.setOperationName( new QName("apachesoap:MatrixService", "sendFile") );
QName fileAttachment = new QName("apachesoap:MatrixService", "DataHandler");

After this you need to define map for the same using registerTypeMapping.



标签: java axis