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

Spring Boot SOAP端点无法接收application/xml请求返回500错误如何修复

问题根因

报错是因为SAAJ(SOAP with Attachments API for Java)的默认实现仅将text/xml识别为合法的SOAP请求Content-Type,对application/xml会直接抛出格式校验错误。


方案1:自定义SaajSoapMessageFactory扩展支持的Content-Type(推荐)

直接扩展Spring WS的SaajSoapMessageFactory,重写createWebServiceMessage方法,在创建SOAP消息前统一将application/xml的请求头替换为合法的text/xml即可,不需要修改现有业务端点逻辑。

自定义消息工厂代码:

import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.springframework.ws.transport.TransportInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;

public class CustomSaajSoapMessageFactory extends SaajSoapMessageFactory {
    @Override
    public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
        if (inputStream instanceof TransportInputStream transportInputStream) {
            Iterator<Map.Entry<String, String>> headers = transportInputStream.getHeaders();
            while (headers.hasNext()) {
                Map.Entry<String, String> header = headers.next();
                if ("Content-Type".equalsIgnoreCase(header.getKey()) 
                    && "application/xml".equalsIgnoreCase(header.getValue().trim())) {
                    // 替换为SAAJ可识别的text/xml格式
                    header.setValue("text/xml");
                    break;
                }
            }
        }
        return super.createWebServiceMessage(inputStream);
    }
}

注册自定义工厂到Spring容器:

在你的WS配置类中替换默认的SaajSoapMessageFactory即可:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import com.sun.xml.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl;

@Configuration
public class WebServiceConfig {
    @Bean
    public SaajSoapMessageFactory messageFactory() {
        // 若你的SOAP版本为1.1,将SOAPMessageFactory1_2Impl替换为SOAPMessageFactory1_1Impl即可
        CustomSaajSoapMessageFactory factory = new CustomSaajSoapMessageFactory();
        factory.setMessageFactory(new SOAPMessageFactory1_2Impl());
        return factory;
    }
}

方案2:添加Servlet过滤器全局替换Content-Type

如果不想修改WS相关配置,也可以新增全局请求过滤器,在请求进入WS Servlet前就将Content-Type替换为text/xml:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class ContentTypeRewriteFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        // 仅匹配你的SOAP端点路径,避免影响其他接口
        if ("application/xml".equalsIgnoreCase(req.getContentType()) 
            && req.getRequestURI().startsWith("/v1/serverEndpoint")) {
            HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(req) {
                private final Map<String, String> customHeaders = new HashMap<>();
                {
                    customHeaders.put("Content-Type", "text/xml");
                }
                @Override
                public String getHeader(String name) {
                    if ("Content-Type".equalsIgnoreCase(name)) {
                        return customHeaders.get(name);
                    }
                    return super.getHeader(name);
                }
                @Override
                public Enumeration<String> getHeaders(String name) {
                    if ("Content-Type".equalsIgnoreCase(name)) {
                        return Collections.enumeration(Collections.singletonList(customHeaders.get(name)));
                    }
                    return super.getHeaders(name);
                }
            };
            chain.doFilter(wrapper, response);
            return;
        }
        chain.doFilter(request, response);
    }
}

将过滤器注册到Spring Boot容器后即可生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:30:03