skip to content

Spring Web Services (SOAP)

Spring Web Services for SOAP: contract-first endpoints from an XSD, generated WSDL, marshalling, the client template and WS-Security. Interviewers ask about it in enterprise and integration roles where SOAP is still the interface to a partner or a mainframe.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

14

What is Jaxb2Marshaller in Spring Web Services and what does it do?

level: juniorimportance: must knowfreq 55%

answer

  1. Marshaller + Unmarshaller, both interfaces
  2. wraps JAXBContext, expensive -> singleton bean
  3. contextPath vs classesToBeBound
  4. no @XmlRootElement -> wrap in JAXBElement
  5. org.springframework.oxm.jaxb

basics

~10 s

Jaxb2Marshaller is a Spring adapter around JAXB that converts Java objects to XML (marshal) and XML back to Java objects (unmarshal), so you work with typed objects instead of raw XML in SOAP messages.

solid answer

~40 s

Jaxb2Marshaller is Spring WS's implementation of both the Marshaller and Unmarshaller interfaces, backed by JAXB (Jakarta XML Binding). It maps annotated Java classes (@XmlRootElement, @XmlType) to and from XML: marshal() writes an object to XML, unmarshal() reads XML into an object. You configure it either with setContextPath("com.example.generated") pointing at a package of JAXB-generated classes containing an ObjectFactory/jaxb.index, or with setClassesToBeBound(...) listing bound classes. It is used on both the client (WebServiceTemplate's marshaller/unmarshaller) and server (marshalling endpoints via @PayloadRoot / MarshallingPayloadMethodProcessor). It centralises XML binding so endpoint and client code deal in POJOs, not DOM. It caches a JAXBContext, which is expensive to build, so it's meant to be a singleton bean.

code

java · 14 lines
java
@Configuration
public class OxmConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // Package(s) of JAXB-generated classes (must contain ObjectFactory / jaxb.index)
        marshaller.setContextPath("com.example.ws.generated");
        // Optional: pretty-print + XSD validation
        marshaller.setMarshallerProperties(
            Map.of(jakarta.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true));
        return marshaller; // singleton: JAXBContext is built once and cached
    }
}

go deeper

for a junior

Know it converts objects <-> XML for SOAP and that you configure a context path or classes to bind.

for a middle

Explain both interfaces, the JAXBContext caching/singleton point, and contextPath vs classesToBeBound.

for a senior

Discuss @XmlRootElement/JAXBElement wrapping, schema validation, exception hierarchy, and use on both client and server.

for a principal

Reason about jakarta vs javax migration, MTOM, performance of JAXBContext, and OXM abstraction letting you swap marshallers.

**The problem it solves.** SOAP web services exchange XML. Working with raw XML (DOM, SAX) in business code is tedious and error-prone. *Marshalling* is the general technique of converting an in-memory object graph to a serialized form (here, XML) and back. Spring WS abstracts this behind two interfaces in `org.springframework.oxm`: `Marshaller` (object -> XML, `marshal(Object, Result)`) and `Unmarshaller` (XML -> object, `unmarshal(Source)`). **What Jaxb2Marshaller is.** `org.springframework.oxm.jaxb.Jaxb2Marshaller` implements *both* interfaces using **JAXB** (Jakarta XML Binding, formerly `javax.xml.bind`, now `jakarta.xml.bind`). JAXB itself maps Java classes annotated with `@XmlRootElement`, `@XmlType`, `@XmlElement`, `@XmlAttribute` etc. to XML. Jaxb2Marshaller wraps a `JAXBContext` and exposes it through the Spring OXM interfaces so the rest of Spring WS can stay binding-technology-agnostic (you could swap in a CastorMarshaller, Jibx, etc. historically). **Configuration — two mutually-common styles:** - `setContextPath("com.example.ws.generated")` — a colon-separated list of packages. Each package must contain JAXB metadata: either an `ObjectFactory` class or a `jaxb.index` file listing the bound classes. This is the normal setup when you generate classes from a WSDL/XSD with the JAXB XJC tool. - `setClassesToBeBound(Order.class, Customer.class, ...)` — you enumerate the annotated classes explicitly. Handy for hand-written POJOs. - `setPackagesToScan("com.example.model")` — scans for `@XmlRootElement`/`@XmlType` classes. Only set one of these. You can also set `setMarshallerProperties(Map)` (e.g. `Marshaller.JAXB_FORMATTED_OUTPUT = true`) and a `setSchema(Resource)` to enable XSD validation during marshal/unmarshal. **How it's used.** - *Client side:* you inject it into `WebServiceTemplate` via `setMarshaller` and `setUnmarshaller` (often the same instance since Jaxb2Marshaller is both). Then `webServiceTemplate.marshalSendAndReceive(requestObject)` returns a response object. - *Server side:* Spring WS's `MarshallingPayloadMethodProcessor` uses it so an `@Endpoint` method can take a JAXB request object as its parameter and return a JAXB response object, with the framework marshalling around it. **Key gotchas / edge cases:** - **JAXBContext is expensive to build** and thread-safe once built. Jaxb2Marshaller builds it lazily and caches it, so define it as a **singleton bean** — do not create one per request. - **`@XmlRootElement` vs no root element.** If a class has no `@XmlRootElement` (common with XJC-generated types), you cannot marshal it directly; you must wrap it in a `JAXBElement<T>` (usually produced by the generated `ObjectFactory.createXxx(...)`), or the marshaller throws about a missing root element. - **`mtomEnabled` / `supportJaxbElementClass`** are extra flags for binary attachments and raw `JAXBElement` support. - **Validation** via `setSchema` throws `UnmarshallingFailureException`/`MarshallingFailureException` (Spring's unified `XmlMappingException` hierarchy) on schema violations. - On Jakarta EE 9+ / Spring 6 the API is `jakarta.xml.bind.*`; on older Spring it was `javax.xml.bind.*`. Getting the wrong JAXB runtime on the classpath is a classic 'no implementation of JAXB found' error. **When to use it.** Any time you build a SOAP client or a contract-first SOAP endpoint in Spring WS and want to work with typed objects rather than DOM/StAX. It is the default and recommended OXM marshaller today.

  • Why should Jaxb2Marshaller be a singleton bean?
    Because it builds and caches a JAXBContext, which is expensive to construct but thread-safe once built. Recreating it per request wastes CPU and memory; sharing one instance is both correct and efficient.
  • You try to marshal a JAXB-generated class and get an error about a missing root element. Why?
    The class lacks @XmlRootElement (common for XJC-generated complex types). Wrap it in a JAXBElement<T> — typically via the generated ObjectFactory.createXxx(...) — so the marshaller knows the root element name and namespace.

saying these in an interview costs you the question

  • Thinking Jaxb2Marshaller only marshals (it also unmarshals — it implements both interfaces)
  • Creating a new Jaxb2Marshaller/JAXBContext per request
  • Believing every JAXB class is directly marshallable without @XmlRootElement or a JAXBElement wrapper
  • Confusing setContextPath (package names) with setClassesToBeBound (class objects) and setting both

context

open as a page

How does @PayloadRoot map a SOAP request to a handler method, and what are its namespace and localPart attributes?

level: middleimportance: must knowfreq 45%

basics

~20 s

@PayloadRoot maps a method to the root XML element of the SOAP body. namespace is that element's XML namespace URI, localPart is its element name. Spring-WS matches the incoming payload's root element by this qualified name and calls the method.

open as a page

How do you wire MessageDispatcherServlet with ServletRegistrationBean in a Spring Boot app, and why can't you reuse the default DispatcherServlet?

level: middleimportance: must knowfreq 55%

basics

~10 s

Register MessageDispatcherServlet as a separate servlet via a ServletRegistrationBean mapped to something like /ws/*. It's Spring-WS's own front controller for SOAP; the regular DispatcherServlet handles MVC/REST, not SOAP message dispatching or WSDL serving.

open as a page

In Spring Web Services, what is a contract-first SOAP endpoint and what does the @Endpoint annotation do?

level: juniorimportance: should knowfreq 35%

basics

~10 s

Contract-first means you write the XML schema (XSD/WSDL) first, then code against it. @Endpoint marks a class as a Spring-WS handler for SOAP requests — like @Controller but for SOAP instead of REST.

open as a page

What is dynamic WSDL generation in Spring Web Services, and how does DefaultWsdl11Definition produce it?

level: juniorimportance: should knowfreq 45%

basics

~10 s

Spring-WS generates the WSDL at runtime from your XSD schema instead of you hand-writing it. You declare a DefaultWsdl11Definition bean pointing at an XsdSchema, and Spring builds the WSDL from that schema on request.

open as a page

What do @RequestPayload and @ResponsePayload do, and how do request/response objects get converted to and from XML?

level: middleimportance: should knowfreq 38%

basics

~10 s

@RequestPayload unmarshals the incoming SOAP body XML into a Java object parameter; @ResponsePayload marshals the returned Java object back into the SOAP body XML. The conversion is done by a configured marshaller, typically JAXB.

open as a page

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

level: middleimportance: should knowfreq 45%

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.

open as a page

Explain how PayloadRootAnnotationMethodEndpointMapping works and where it fits in the Spring-WS request-processing pipeline.

level: seniorimportance: should knowfreq 28%

basics

~10 s

It's the endpoint mapping that inspects the SOAP payload's root element QName and routes to the @Endpoint method with the matching @PayloadRoot. It sits inside the MessageDispatcher, chosen after MessageDispatcherServlet receives the SOAP request.

open as a page

How do you add WS-Security username/password authentication to a Spring WS client or endpoint with Wss4jSecurityInterceptor?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Add a Wss4jSecurityInterceptor to the client's or endpoint's interceptor chain. For outgoing messages set securementActions='UsernameToken' with a username, password, and password type (Digest or Text); for incoming ones set validationActions='UsernameToken' plus a callback handler that checks the credentials.

open as a page

How does DefaultWsdl11Definition decide which schema elements become WSDL operations, and how do requestSuffix/responseSuffix and multiple schemas factor in?

level: seniorimportance: should knowfreq 35%

basics

~20 s

It scans top-level XSD element declarations and pairs those ending in the request suffix ('Request' by default) with matching 'Response' ones, turning each pair into a WSDL operation. You can change the suffixes; multiple schemas need a schema collection.

open as a page

How does Wss4jSecurityInterceptor sign and encrypt SOAP messages, and what infrastructure does that require?

level: seniorimportance: nice to knowfreq 22%

basics

~20 s

You add 'Signature' and/or 'Encrypt' to the interceptor's securement/validation actions and supply a WSS4J Crypto (backed by a keystore) plus key aliases and passwords. Signing proves integrity/authenticity with the sender's private key; encryption protects confidentiality using the recipient's public key.

open as a page

As an architect, how do you justify contract-first SOAP over contract-last, and how do you evolve an XSD-driven contract without breaking existing clients?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Contract-first keeps the XML contract stable and language-neutral so many clients can rely on it, instead of it drifting with Java refactors. To evolve safely, make additive/optional changes, and for breaking changes publish a new XSD namespace version so old clients keep working.

open as a page

When would you choose message-level WS-Security over transport TLS for a SOAP integration, and how do the marshaller, WebServiceTemplate, and Wss4jSecurityInterceptor fit together?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Use WS-Security when security must travel with the message — across intermediaries, for non-repudiation, or for partial (per-element) protection — versus TLS which only secures a single point-to-point hop. In the client, Jaxb2Marshaller maps objects<->XML, WebServiceTemplate sends the SOAP call, and Wss4jSecurityInterceptor sits in its interceptor chain adding/validating WS-Security headers.

open as a page

A client fetches the generated WSDL through a load balancer and the soap:address points to an internal host. How does Spring-WS solve this, and what are the tradeoffs of location transformation?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

Enable setTransformWsdlLocations(true) on MessageDispatcherServlet. Spring-WS then rewrites the soap:address location in the served WSDL to match the host, port, and path the client actually used, so proxied clients get a reachable endpoint instead of the static locationUri.

open as a page