Spring Boot SOAP Web服务请求全失败,访问WSDL报404错误
问题
开发的Spring Boot SOAP Web服务构建部署无错误,但请求始终返回404,且服务日志无请求接收记录:
- 访问
http://localhost:8080/ws/hello.wsdl返回404,JSON响应如下:
{ "timestamp": "2025-05-26T10:23:07.533+00:00", "status": 404, "error": "Not Found", "path": "/ws/hello.wsdl" }
浏览器访问该地址显示白标错误页:
Whitelabel Error Page This application has no explicit mapping for /error, so you see this as a fallback. Mon May 26 15:55:29 IST 2025 There was an unexpected error (type=Not Found, status=404).
- 向
http://localhost:8080/ws发送POST请求(请求内容如下)同样返回404:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ex="http://example.com/soap-web-service"> <soapenv:Header/> <soapenv:Body> <ex:GetHelloRequest> <name>John Doe</name> </ex:GetHelloRequest> </soapenv:Body> </soapenv:Envelope>
以下是项目相关代码、配置及结构:
HelloEndpoint.java
package com.example.soap_web_service; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload; @Endpoint public class HelloEndpoint { private static final String NAMESPACE_URI = "http://example.com/soap-web-service"; @PayloadRoot(namespace = NAMESPACE_URI, localPart = "GetHelloRequest") @ResponsePayload public GetHelloResponse sayHello(@RequestPayload GetHelloRequest request) { GetHelloResponse response = new GetHelloResponse(); response.setGreeting("Hello, " + request.getName() + "!"); return response; } }
WebServiceConfig.java
import org.springframework.context.ApplicationContext; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema; @Configuration @EnableWs public class WebServiceConfig { @Bean public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet( ApplicationContext applicationContext) { MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(applicationContext); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean<>(servlet, "/ws/*"); } @Bean(name = "hello") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema helloSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); wsdl11Definition.setPortTypeName("HelloPort"); wsdl11Definition.setLocationUri("/ws"); wsdl11Definition.setTargetNamespace("http://example.com/soap-web-service"); wsdl11Definition.setSchema(helloSchema); return wsdl11Definition; } @Bean public XsdSchema helloSchema() { return new SimpleXsdSchema(new ClassPathResource("hello.xsd")); } }
SoapWebServiceApplication.java
package com.example.soap_web_service; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SoapWebServiceApplication { public static void main(String[] args) { SpringApplication.run(SoapWebServiceApplication.class, args); } }
hello.wsdl
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://example.com/soap-web-service" targetNamespace="http://example.com/soap-web-service"> <!-- Import your XSD schema --> <types> <xsd:schema> <xsd:import namespace="http://example.com/soap-web-service" schemaLocation="hello.xsd"/> </xsd:schema> </types> <!-- Reference the schema elements instead of types --> <message name="GetHelloRequest"> <part name="parameters" element="tns:GetHelloRequest"/> </message> <message name="GetHelloResponse"> <part name="parameters" element="tns:GetHelloResponse"/> </message> <portType name="HelloPortType"> <operation name="getHello"> <input message="tns:GetHelloRequest"/> <output message="tns:GetHelloResponse"/> </operation> </portType> <binding name="HelloBinding" type="tns:HelloPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getHello"> <soap:operation soapAction="http://example.com/soap-web-service/getHello"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="HelloService"> <port name="HelloPort" binding="tns:HelloBinding"> <soap:address location="http://localhost:8080/soap-api"/> </port> </service> </definitions>
hello.xsd
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/soap-web-service" xmlns:tns="http://example.com/soap-web-service" elementFormDefault="qualified"> <xsd:element name="GetHelloRequest"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="GetHelloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="greeting" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>soap-web-service</artifactId> <version>1.0.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.5</version> <relativePath/> </parent> <properties> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <!-- Spring Boot Web (for ServletRegistrationBean) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Web Services --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> <!-- JAXB dependencies --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.1</version> </dependency> <!-- Test Support --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.3</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- JAXB Code Generation Plugin --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>xjc</id> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <sources> <source>src/main/resources/hello.xsd</source> </sources> <packageName>com.example.soap_web_service</packageName> <outputDirectory>${project.build.directory}/generated-sources/jaxb</outputDirectory> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>3.6.0</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.build.directory}/generated-sources/jaxb</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
项目结构
. ├── compose.yaml ├── HELP.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ └── soap_web_service │ │ │ ├── HelloEndpoint.java │ │ │ ├── SoapWebServiceApplication.java │ │ │ └── WebServiceConfig.java │ │ └── resources │ │ ├── application.properties │ │ ├── hello-soapui-project.xml │ │ ├── hello.wsdl │ │ ├── hello.xsd │ │ ├── static │ │ ├── templates │ │ └── wsdl │ │ ├── hello.wsdl │ │ └── hello.xsd │ └── test │ └── java │ └── com │ └── example │ └── soap_web_service │ └── SoapWebServiceApplicationTests.java └── target
问题排查与解决
1. 核心问题:配置类未被Spring扫描加载
原WebServiceConfig.java缺少包声明,导致它不在com.example.soap_web_service包下,而@SpringBootApplication默认只扫描主类所在包及子包的组件,因此SOAP服务的核心配置(MessageDispatcherServlet、WSDL定义、Endpoint)都未被加载,这是404的根本原因。
修复方案
给WebServiceConfig.java添加包声明,并确保Spring能扫描到同包下的Endpoint:
package com.example.soap_web_service; import org.springframework.context.ApplicationContext; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ComponentScan; import org.springframework.core.io.ClassPathResource; import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema; @Configuration @EnableWs @ComponentScan(basePackages = "com.example.soap_web_service") public class WebServiceConfig { // 原代码内容不变 }
2. WSDL访问路径与自定义文件问题
- Spring WS通过
DefaultWsdl11Definition生成的WSDL访问路径为http://localhost:8080/ws/hello.wsdl或http://localhost:8080/ws/hello,修复配置后即可正常访问。 - 自定义的
hello.wsdl中,soap:address的location设置为http://localhost:8080/soap-api,与实际服务路径/ws不符,若使用该文件调用服务,需修改为http://localhost:8080/ws;若依赖Spring自动生成的WSDL,该自定义文件可移除。
3. 验证与调试步骤
- 重新构建项目:执行
mvn clean package确保代码生效。 - 启动服务后,访问
http://localhost:8080/ws/hello.wsdl,确认能看到WSDL内容。 - 发送POST请求时,需设置请求头
Content-Type: text/xml,请求地址为http://localhost:8080/ws,请求体使用提供的SOAP信封。 - 若仍有问题,在
application.properties中添加日志配置,查看服务启动时的组件加载情况:
logging.level.org.springframework.ws=DEBUG logging.level.org.springframework.web=DEBUG
日志中应能看到Endpoint注册、Servlet映射的相关记录,确认配置已生效。
内容的提问来源于stack exchange,提问作者Gehan
相关产品推荐
相关产品推荐

