You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 验证与调试步骤

  1. 重新构建项目:执行mvn clean package确保代码生效。
  2. 启动服务后,访问http://localhost:8080/ws/hello.wsdl,确认能看到WSDL内容。
  3. 发送POST请求时,需设置请求头Content-Type: text/xml,请求地址为http://localhost:8080/ws,请求体使用提供的SOAP信封。
  4. 若仍有问题,在application.properties中添加日志配置,查看服务启动时的组件加载情况:
logging.level.org.springframework.ws=DEBUG
logging.level.org.springframework.web=DEBUG

日志中应能看到Endpoint注册、Servlet映射的相关记录,确认配置已生效。

内容的提问来源于stack exchange,提问作者Gehan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:02:04