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

Spring Boot实现SOAP客户端调用报错Invalid Content-Type:text/html如何解决

问题修复方案

根因说明

你遇到的错误本质是请求格式完全不符合服务端预期,服务端返回PHP错误页面(Content-Type为text/html),才触发解析报错,具体问题点:

  1. setDefaultUri配置错误:该参数需要填SOAP服务的实际接口地址,不是WSDL地址
  2. 请求根节点错误:你当前用loginDataClass作为Body下的根节点,服务端要求的根节点是login
  3. 命名空间错误:根节点的命名空间填了SOAP编码的地址,实际需要用服务端业务命名空间https://xpartner.net.pl/xpartner/
  4. 参数结构错误:服务端要求login节点下嵌套obj节点,再放账号密码参数,你当前直接把账号密码放在loginDataClass下

分步修改代码

1. 修正配置类的默认地址

client.setDefaultUri填写服务端接口地址https://xpartner.net.pl/wsdlSoapServ2.php,修正后的配置类代码:

@Configuration
public class XpartnerConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.autokonto.pl.xpartner");
        return marshaller;
    }

    // 可选配置:强制指定请求Content-Type为text/xml
    @Bean
    public SaajSoapMessageFactory soapMessageFactory() {
        SaajSoapMessageFactory factory = new SaajSoapMessageFactory();
        factory.setSoapVersion(SoapVersion.SOAP_11);
        return factory;
    }

    @Bean
    public XpartnerClient xpartnerClient(Jaxb2Marshaller marshaller, SaajSoapMessageFactory soapMessageFactory) {
        XpartnerClient client = new XpartnerClient();
        // 这里填服务端接口地址,不是WSDL地址
        client.setDefaultUri("https://xpartner.net.pl/wsdlSoapServ2.php");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        client.setMessageFactory(soapMessageFactory);
        return client;
    }
}

2. 修正请求结构与命名空间

你之前直接将LoginDataClass作为根节点发送,需要先包装成服务端要求的login节点,且正确设置命名空间:

@Slf4j
@Service
@RequiredArgsConstructor
public class XpartnerApiService {
    // 修正QName:命名空间改为业务命名空间,节点名改为login
    private final static javax.xml.namespace.QName _LOGIN_QNAME = new javax.xml.namespace.QName("https://xpartner.net.pl/xpartner/", "login");

    @Value("${xpartner.login}")
    private String login;
    @Value("${xpartner.password}")
    private String password;

    LoginResultClass loginResultClass;

    private final XpartnerClient xpartnerClient;

    @PostConstruct
    void login() {
        log.info("log in xpartnerClient");
        ObjectFactory objectFactory = new ObjectFactory();

        // 构造账号密码对象
        LoginDataClass data = objectFactory.createLoginDataClass();
        data.setLogin(login);
        data.setPass(password);

        // 构造obj节点,嵌套账号密码
        JAXBElement<LoginDataClass> objElement = new JAXBElement<>(new QName("https://xpartner.net.pl/xpartner/", "obj"), LoginDataClass.class, data);
        
        // 构造根节点login,嵌套obj
        JAXBElement<JAXBElement> loginElement = new JAXBElement<>(_LOGIN_QNAME, JAXBElement.class, objElement);

        this.loginResultClass = xpartnerClient.login(loginElement);
        log.info("LOGGING RESULT" + loginResultClass.isLoginResult());
    }
}

3. 客户端代码无需修改,保持原有逻辑即可

@Slf4j
public class XpartnerClient extends WebServiceGatewaySupport {

    public LoginResultClass login(JAXBElement<?> loginRequest) {
        LoginResultClass response = (LoginResultClass) getWebServiceTemplate().marshalSendAndReceive(loginRequest);
        return response;
    }
}

额外说明

如果JAXB插件已经根据WSDL生成了Login请求类,直接用该类构造请求即可,不需要手动包装QName,逻辑会更简洁。上述通用方案适配你当前已生成的类结构,调整后请求格式就会和你预期的一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:39:04