Spring Boot Bottom-Up SOAP Service Example
By Ercan - 22/10/2025
SOAP services are still widely used in enterprise systems and legacy integrations.
However, new Spring Boot developers often struggle with WSDL, XSD, and Jakarta namespaces.
In this blog, we will create a bottom-up SOAP service where the WSDL is automatically generated from Java classes and annotations.
The project uses jaxws-spring-jakarta, a modernized SOAP runtime compatible with Spring Boot 3.
TL;DR: If you want to skip the explanation and dive straight into the code, check out the full implementation on GitHub: https://github.com/ercansormaz/soap-producer-bottom-up
Bottom-Up vs Top-Down SOAP
There are two main approaches to building SOAP web services:
Bottom-Up (Code-First)
- Start by writing Java classes and annotating them with
@WebService,@WebParam,@WebResult, etc. - The WSDL file is generated automatically.
- Quick to implement and easy to maintain, ideal for internal APIs.
Top-Down (Contract-First)
- Start with a predefined WSDL, then generate server and client stubs using tools like
wsimport. - Ensures strict contract adherence, suitable for inter-organizational integrations.
Our example project uses the bottom-up approach, providing a simple way to expose existing Java classes as SOAP services in Spring Boot 3 and Jakarta EE.
Example Project: Calculator SOAP Service
Service Features
- Addition, subtraction, multiplication, division
- Automatic WSDL generation
- Endpoint: http://localhost:8080/SOAP/CalculatorService
Sample Code
@WebService(targetNamespace = "https://ercan.dev/poc/soap-producer-bottom-up/calculator")
public class CalculatorService {
public SumResult sum(SumRequest request) {
SumResult response = new SumResult();
response.setResult(request.getNumber1() + request.getNumber2());
return response;
}
// subtract, multiply, divide methods omitted for brevity
}
Configuration
@Bean
public ServletRegistrationBean<SoapServiceServlet> SoapServiceServlet() {
SoapServiceServlet soapWsServlet = new SoapServiceServlet();
ServletRegistrationBean<SoapServiceServlet> bean = new ServletRegistrationBean<>(soapWsServlet);
bean.setLoadOnStartup(1);
return bean;
}
@Bean
public SoapServiceBinding calculatorServiceBinding(CalculatorService calculatorService) throws Exception {
SoapServiceFactory soapServiceFactory = new SoapServiceFactory();
soapServiceFactory.setBean(calculatorService);
SoapServiceBinding soapServiceBinding = new SoapServiceBinding();
soapServiceBinding.setUrl("/SOAP/CalculatorService");
soapServiceBinding.setService(soapServiceFactory.getObject());
return soapServiceBinding;
}
SOAP Request Example
Addition (sum) request:
curl --location 'http://localhost:8080/SOAP/CalculatorService' \
--header 'Content-Type: text/xml;charset=UTF-8' \
--data '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="https://ercan.dev/poc/soap-producer-bottom-up/calculator">
<soapenv:Header/>
<soapenv:Body>
<cal:sum>
<!--Optional:-->
<request>
<number1>5</number1>
<number2>3</number2>
</request>
</cal:sum>
</soapenv:Body>
</soapenv:Envelope>'
Response:
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:sumResponse xmlns:ns2="https://ercan.dev/poc/soap-producer-bottom-up/calculator">
<response>
<result>8</result>
</response>
</ns2:sumResponse>
</S:Body>
</S:Envelope>
Running the Service
Maven
mvn clean spring-boot:run
Gradle
./gradlew bootRun
Then open the WSDL in your browser:
http://localhost:8080/SOAP/CalculatorService?wsdl
Tip: Import the WSDL into SOAP UI to generate client stubs and test the service.
Conclusion
In this tutorial, we demonstrated bottom-up SOAP service development with Spring Boot 3.
The Calculator SOAP Service is a simple example, but the same approach can be applied to more complex business logic.
👉 You can explore the full source code on GitHub:
https://github.com/ercansormaz/soap-producer-bottom-up
Tags: spring boot, web service, soap service, java
