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

Java8迁移至Java21调用SOAP服务报Missing header 'entityType'错误求助

问题分析:Java 8迁移至Java 21后SOAP客户端调用报错

错误信息

org.springframework.ws.soap.client.SoapFaultClientException: Missing header 'entityType' for method parameter type [class java.lang.String]
    at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:39)
    at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:843)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:646)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:575)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:422)
    at com.me.client.ABCClient.callLookoutService(ABCClient.java:425)
    at com.me.client.ABCClient.processLookout(ABCClient.java:262)
    at com.me.client.ABCClient.execute(ABCClient.java:688)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)

触发异常的代码

Response callWebService(Request request)
{
    Response response = new Response();
    try
        {
                JAXBContext jc = JAXBContext.newInstance(Request.class);
                Marshaller marshallerPrint = jc.createMarshaller();
                marshallerPrint.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);
                Writer sw = new StringWriter();

                marshallerPrint.marshal(request, sw);
                            
                //Verify XML Content
                String xmlContent = sw.toString();
                
                Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
                marshaller.setContextPath("xxx.yyy.zzz.wsdl.query.v1");
                
                
                WebServiceTemplate webTemplate= new WebServiceTemplate();
                webTemplate.setMarshaller(marshaller);
                webTemplate.setUnmarshaller(marshaller);

                 response = (Response) webTemplate.marshalSendAndReceive("service_url_here", request, new SoapActionCallback("http://spring.io/guides/gs-producing-web-service/GetCountryRequest"));
                        
        }
        .
        .
        .
}

原因分析及解决方向

  • 核心问题:服务端要求的SOAP请求头entityType未被包含在请求中,这并非Java版本迁移直接导致,而是迁移过程中客户端的头信息配置逻辑出现遗漏,或JAXB在Java 21下的序列化行为变化导致头字段未被正确处理。

  • 可能的具体原因

    1. 原Java 8环境中自动添加entityType头的配置(如注解、自定义回调、Spring配置)在迁移时未同步。
    2. Java 21使用的JAXB实现(如EclipseLink MOXy)与Java 8内置JAXB的默认行为存在差异,导致原本能自动映射的头字段失效。
    3. 当前代码仅设置了SoapAction,未显式添加entityType这个自定义请求头。
  • 解决步骤建议

    1. 回溯原Java 8客户端代码/配置,确认之前是如何添加entityType头的,比如是否使用@SoapHeader注解、自定义WebServiceMessageCallback实现。
    2. 修改代码,在请求回调中手动添加entityType头,示例如下:
      response = (Response) webTemplate.marshalSendAndReceive("service_url_here", request, new WebServiceMessageCallback() {
          @Override
          public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
              // 设置SoapAction
              ((SoapMessage) message).setSoapAction("http://spring.io/guides/gs-producing-web-service/GetCountryRequest");
              // 添加entityType头
              SoapHeader header = ((SoapMessage) message).getSoapHeader();
              // 替换为实际的命名空间和头值
              QName qName = new QName("http://your-service-namespace", "entityType");
              SoapHeaderElement headerElement = header.addHeaderElement(qName);
              headerElement.setText("your-entity-type-value");
          }
      });
      
    3. 验证Jaxb2Marshaller的contextPath是否包含了定义SOAP头的类,确保所有需要序列化的类都被覆盖。
    4. 抓包对比Java 8和Java 21环境下的SOAP请求内容,确认entityType头的存在情况,定位具体差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:43:28