12
votes

I am using Spring boot to call a webservice.

my config class is as:

@Configuration
public class ClientAppConfig {
@Bean
public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setPackagesToScan("com.client.stub");
    return marshaller;
}

@Bean
public ARTestClient arTestClient(Jaxb2Marshaller marshaller) {
    ARTestClient client = new ARTestClient();
    client.setDefaultUri("uri");
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
   return client;
}

i am calling service as following:

    OutputMessageType response = (OutputMessageType) getWebServiceTemplate().marshalSendAndReceive(
            inputMessageType, new SoapActionCallback("http://Serviceuri"));

I am getting following error:

   [2016-03-18 14:45:43.697] boot - 10272 ERROR [http-nio-8080-exec-1] --- [dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 
  [Request processing failed; nested exception is java.lang.ClassCastException: javax.xml.bind.JAXBElement 
  cannot be cast to com.wfs.client.stub.ar.OutputMessageType] with root cause

How to unMarshal the output from webservice????? How do i set unmarshaller for the response??

3

3 Answers

29
votes

Funny I JUST had the same issue, here's what I did :

Cast your response to a

JAXBElement<OutputMessageType>

So the result would be

JAXBElement<OutputMessageType> response = (JAXBElement<OutputMessageType>) getWebServiceTemplate().marshalSendAndReceive(
        inputMessageType, new SoapActionCallback("http://Serviceuri"));
// Then just call
System.out.println(response.getValue());

I have about the same configurations as you. I'm still trying to figure out why there's a ClassCastException. At least we have a workaround...

8
votes

If it is still relevant today, there is a way to solve this issue in the config file. Instead of using .setPackagesToScan in the following line: marshaller.setPackagesToScan("com.client.stub")
consider using .setClassesToBeBound
However, you will need to reference each class (that will be used for marshalling and unmarshalling) under your package:

   marshaller.setClassesToBeBound(new Class[] { 
       com.client.stub.Foo.class,
       com.client.stub.Bar.class,
       com.client.stub.Baz.class
   });

There is no need to cast to JAXBElement.

2
votes
    JAXBElement<OutputMessageType> response = (JAXBElement<OutputMessageType>) 
    getWebServiceTemplate().marshalSendAndReceive(
    inputMessageType, new SoapActionCallback("http://Serviceuri"));
    // Then just call 
     System.out.println(response.getValue());

worked well for my case