[SOLVED] Not able to call SOAP API in WebServiceGatewaySupport by Spring WebServiceTemplate – Need help to fix this issue

Issue

This Content is from Stack Overflow. Question asked by BALA AP

I am trying to call SOAP API in Java spring spoot using WebServiceGatewaySupport by Spring WebServiceTemplate

Config java class

public WebServiceTemplate createWebServiceTemplate(Jaxb2Marshaller marshaller, ClientInterceptor clientInterceptor) {

        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        
        //SOAP URL
        webServiceTemplate.setDefaultUri("http://host/Services.asmx");
        
        
        //Auth ---It seems issue is here only????? need to check
        webServiceTemplate.setMessageSender(new Authentication());
                 
        webServiceTemplate.setMarshaller(marshaller);
        webServiceTemplate.setUnmarshaller(marshaller);
        
        webServiceTemplate.afterPropertiesSet();
        webServiceTemplate.setCheckConnectionForFault(true);
        webServiceTemplate.setInterceptors((ClientInterceptor[]) Arrays.asList(createLoggingInterceptor()).toArray());     
        return webServiceTemplate;
}

SOAP Client Call

public class TicketClient extends WebServiceGatewaySupport {

public String    getTicket(Ticket req) {

    System.out.println("test inside webservice support1");
    
        response = (AcquireTicketResponse) getWebServiceTemplate().marshalSendAndReceive(req);

I am getting below error….I checked in ISS side…I am seeing in only connection but no other details….It seems AUTHENTICATION IS NOT passing properly but not sure i am not able to pin point the issue.

Could not use transport: Internal Server Error [500]
org.springframework.ws.client.WebServiceTransportException: Internal Server Error [500]
test inside———–>Webservice call error
at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:673)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:591)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:542)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:394)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:388)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
at qa.com.prime.soapservices.config.AcquireTicketClient.getAcquireTicket(AcquireTicketClient.java:56)
at qa.com.prime.soapservices.SoapservicesApplication.lambda$0(SoapservicesApplication.java:31)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:755)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at qa.com.prime.soapservices.SoapservicesApplication.main(SoapservicesApplication.java:16)



Solution

First of all don’t set the content type Spring WebServices will do that for you, messing around with that will only make things worse.

You should get the WebServiceConnection and cast that to a HeadersAwareSenderWebServiceConnection to add a header.

public class BasicAuthenticationInterceptor implements ClientInterceptor {

  @Override
  public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
    String username="test@test";
    String password="test";
    byte[] userpassword = (username+":"+password).getBytes(UTF_8);        
    String encoded = Base64.getEncoder().encodeToString(userpassword);       
     
    WebServiceConnection conn = TransportContext.getConnection();
    ((HeadersAwareSenderWebServiceConnection) conn).addHeader("Authorization", "Basic " + encoded);
  }
}

You also need to configure it. Assuming it is a bean don’t call afterPropertiesSet (and ofcourse you are now using the ClientInterceptor remove the new Authentication() for your customized message sender.

The List<ClientInterceptor> will automatically create a list with all the interceptors so you can easily inject them.

@Bean
public WebServiceTemplate createWebServiceTemplate(Jaxb2Marshaller marshaller, List<ClientInterceptor> clientInterceptors) {
        
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);       
    //SOAP URL
    webServiceTemplate.setDefaultUri("http://host/Services.asmx");
    webServiceTemplate.setCheckConnectionForFault(true);
    webServiceTemplate.setInterceptors(clientInterceptors);     
    return webServiceTemplate;
}

If this doesn’t work there is something else you are doing wrong and you will need to get in touch with the server developers and get more information on the error.

Update:

Apparently you also need to provide a SOAP Action in your request, which you currently don’t. For this you can specify the SoapActionCallback in the marshalSendAndReceive method. Which action to specify you can find in the WSDL you are using.

SoapActionCallback soapAction = new SoapActionCallback("SoapActionToUse");
response = (AcquireTicketResponse) getWebServiceTemplate().marshalSendAndReceive(req, soapAction);


This Question was asked in StackOverflow by BALA AP and Answered by M. Deinum It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?