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下的序列化行为变化导致头字段未被正确处理。可能的具体原因
- 原Java 8环境中自动添加
entityType头的配置(如注解、自定义回调、Spring配置)在迁移时未同步。 - Java 21使用的JAXB实现(如EclipseLink MOXy)与Java 8内置JAXB的默认行为存在差异,导致原本能自动映射的头字段失效。
- 当前代码仅设置了SoapAction,未显式添加
entityType这个自定义请求头。
- 原Java 8环境中自动添加
解决步骤建议
- 回溯原Java 8客户端代码/配置,确认之前是如何添加
entityType头的,比如是否使用@SoapHeader注解、自定义WebServiceMessageCallback实现。 - 修改代码,在请求回调中手动添加
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"); } }); - 验证
Jaxb2Marshaller的contextPath是否包含了定义SOAP头的类,确保所有需要序列化的类都被覆盖。 - 抓包对比Java 8和Java 21环境下的SOAP请求内容,确认
entityType头的存在情况,定位具体差异。
- 回溯原Java 8客户端代码/配置,确认之前是如何添加
内容的提问来源于stack exchange,提问作者escee999
相关产品推荐
相关产品推荐

