skip to content

How do you call a SOAP service from Spring using WebServiceTemplate?

level: middleimportance: should knowfreq 45%

answer

  1. client template, like RestTemplate for SOAP
  2. marshalSendAndReceive(request)
  3. SoapActionCallback sets SOAPAction
  4. SaajSoapMessageFactory + HttpUrlConnection/HttpComponents sender
  5. SoapFaultClientException on fault; singleton, thread-safe

basics

~10 s

Create a WebServiceTemplate, give it a Jaxb2Marshaller and the service URI, then call marshalSendAndReceive(requestObject). It marshals your object to a SOAP request, sends it over HTTP, and unmarshals the reply into a response object.

solid answer

~40 s

WebServiceTemplate is Spring WS's client-side helper, analogous to RestTemplate/JdbcTemplate. You configure it with a marshaller and unmarshaller (usually one Jaxb2Marshaller for both) and a default URI or a WebServiceMessageSender (HttpUrlConnectionMessageSender or an HttpComponents-based one). The common call is marshalSendAndReceive(requestObject) — it marshals the object into the SOAP body, sends over the transport, and unmarshals the response payload back to an object. You can pass a WebServiceMessageCallback to modify the outgoing message (add SOAP headers, set the SOAP action). It uses a WebServiceMessageFactory (SAAJ by default) to build messages, translates transport/SOAP faults into Spring's WebServiceClientException hierarchy (e.g. SoapFaultClientException), and is thread-safe, so it's wired as a singleton bean. Extending WebServiceGatewaySupport is a convenient base class for typed client beans.

code

java · 18 lines
java
@Bean
public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller) {
    WebServiceTemplate template = new WebServiceTemplate();
    template.setMarshaller(marshaller);
    template.setUnmarshaller(marshaller);
    template.setDefaultUri("https://services.example.com/CountryService");

    HttpUrlConnectionMessageSender sender = new HttpUrlConnectionMessageSender();
    sender.setConnectionTimeout(Duration.ofSeconds(5));
    sender.setReadTimeout(Duration.ofSeconds(10));
    template.setMessageSender(sender);
    return template;
}

// usage
GetCountryResponse response = (GetCountryResponse) template.marshalSendAndReceive(
        new GetCountryRequest("Spain"),
        new SoapActionCallback("http://example.com/GetCountry")); // sets SOAPAction header

go deeper

for a junior

Know it's the SOAP client and that marshalSendAndReceive sends a request object and returns a response object.

for a middle

Explain marshaller/sender/message-factory wiring, SoapActionCallback, and fault-vs-transport exceptions.

for a senior

Discuss interceptor chain (WS-Security hook), HttpComponents pooling/timeouts, SOAP 1.1 vs 1.2, WebServiceGatewaySupport.

for a principal

Weigh transport choices, resilience (timeouts/retries/pooling), testability with MockWebServiceServer, and where WS-Security belongs in the chain.

**What it is.** `org.springframework.ws.client.core.WebServiceTemplate` is the central client-side class in Spring Web Services, following the same 'template' pattern as `RestTemplate` and `JdbcTemplate`: it handles the boilerplate of building a SOAP message, sending it, and reading the response, while you supply the payload and the mapping. **Core collaborators you configure:** - **Marshaller / Unmarshaller** — usually one `Jaxb2Marshaller` set via `setMarshaller` and `setUnmarshaller`. These convert between your Java objects and the XML in the SOAP body. - **WebServiceMessageFactory** — creates the message objects. Default is `SaajSoapMessageFactory` (SAAJ = SOAP with Attachments API for Java). You can pick SOAP 1.1 vs 1.2 here. - **WebServiceMessageSender / transport** — how bytes go over the wire. `HttpUrlConnectionMessageSender` (JDK `HttpURLConnection`) is the simplest; `HttpComponentsMessageSender`/`ClientHttpRequestMessageSender` allow connection pooling, timeouts, auth, and interceptors. - **Default URI** (`setDefaultUri`) — the endpoint the template posts to when you don't pass a URI per call. - **ClientInterceptors** (`setInterceptors`) — cross-cutting hooks; this is where **Wss4jSecurityInterceptor** plugs in for WS-Security. **Main methods:** - `marshalSendAndReceive(Object request)` — marshals `request`, sends, unmarshals the response payload, returns it. The workhorse. - `marshalSendAndReceive(Object request, WebServiceMessageCallback callback)` — same, but the callback lets you mutate the outgoing `WebServiceMessage` before it's sent — e.g. set the SOAP action via `SoapActionCallback`, or add custom SOAP headers. - `sendSourceAndReceiveToResult(Source, Result)` — low-level variant working with raw XML `Source`/`Result` if you're not marshalling. **Error handling.** Transport and protocol problems surface as Spring's unchecked `WebServiceClientException` hierarchy: a SOAP fault in the response becomes `SoapFaultClientException` (you can inspect `getSoapFault()`), transport I/O issues become `WebServiceTransportException`, and marshalling problems bubble as `WebServiceIOException`/OXM exceptions. A default `FaultMessageResolver` decides whether a fault is thrown. **Threading & wiring.** WebServiceTemplate is thread-safe after configuration and is meant to be a **singleton bean**. A common pattern is to subclass `WebServiceGatewaySupport`, which gives you a pre-wired template plus setters for marshaller and sender, and then expose typed methods like `getCountry(String name)`. **Gotchas:** - **SOAP action.** Many services route on the SOAPAction HTTP header. If you don't set it (via `SoapActionCallback`), the server may reject the call. Easy to forget. - **SOAP 1.1 vs 1.2** must match the server; set the right message factory / content type. - **Timeouts.** `HttpUrlConnectionMessageSender` needs `setConnectionTimeout`/`setReadTimeout`; forgetting them risks hung threads. Pooling/timeouts are a reason to prefer `HttpComponentsMessageSender`. - **Namespaces / no root element** — same JAXB caveats as the marshaller; the request object must be marshallable (root element or JAXBElement). - **Faults vs exceptions.** A SOAP fault is a *successful HTTP 200* carrying a `<Fault>`; the template turns it into `SoapFaultClientException`, not a transport error — handle both. **When to use it.** Whenever you consume a SOAP/WSDL service from a Spring app and want typed request/response objects plus pluggable interceptors (including WS-Security).

  • The server routes requests by SOAPAction and your call is rejected. How do you fix it with WebServiceTemplate?
    Pass a WebServiceMessageCallback — specifically a SoapActionCallback with the required action URI — as the second argument to marshalSendAndReceive, which sets the SOAPAction HTTP header on the outgoing message.
  • How does WebServiceTemplate surface a SOAP fault vs a network failure?
    A SOAP fault (HTTP 200 with a <Fault> body) becomes SoapFaultClientException, from which you can read the fault code/string. A transport problem (connect/read failure) becomes WebServiceTransportException/WebServiceIOException. Both extend the unchecked WebServiceClientException hierarchy.

saying these in an interview costs you the question

  • Thinking a SOAP fault arrives as an HTTP 500 / transport error rather than an HTTP-200 fault turned into SoapFaultClientException
  • Forgetting to set the SOAPAction header when the service requires it
  • Creating a new WebServiceTemplate per call instead of a singleton
  • Not configuring connection/read timeouts, risking hung threads

context