JDK11调用SOAP服务遇WebServiceTransportException(404)问题求助
SOAP服务调用404问题排查(JDK11+Gradle迁移后)
问题背景
将JDK8+Maven环境下的SOAP服务调用代码迁移至JDK11+Gradle环境后,JaxB相关错误已解决,且可通过SoapUI正常调用目标SOAP服务,但使用Spring WS的marshalSendAndReceive方法发起调用时,出现org.springframework.ws.client.WebServiceTransportException: Not Found [404]错误。
相关代码
MyServiceConfig.java
package com.mytest.config; import com.mytest.webservice.GetSummaryRequestType; import com.mytest.webservice.GetSummaryResponseType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.oxm.jaxb.Jaxb2Marshaller; @Configuration public class MyServiceConfig { @Bean(name="myMarshaller") public Jaxb2Marshaller myMarshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setClassesToBeBound(GetSummaryRequestType.class, GetSummaryResponseType.class); return marshaller; } }
MyService.java
package com.mytest.service; import javax.xml.bind.JAXBElement; import com.mytest.webservice.KeyType; import com.mytest.webservice.GetSummaryRequestType; import com.mytest.webservice.GetSummaryResponseType; import com.mytest.webservice.ObjectFactory; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.stereotype.Service; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import org.springframework.ws.soap.client.core.SoapActionCallback; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; @Slf4j @Service public class MyService extends WebServiceGatewaySupport { @Autowired @Qualifier("myMarshaller") Jaxb2Marshaller marshaller; @Value("${soapws.url:http://localhost/soapService}") String wsUrl; @Getter private ObjectFactory myServiceObjectFactory = new ObjectFactory(); public GetSummaryResponseType getSummary(int number, String todaysDate, String id, String startTime) throws Exception { try { this.setDefaultUri(wsUrl); KeyType objKey = getMyServiceObjectFactory().createKeyType(); objKey.setNumber(number); XMLGregorianCalendar calDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(todaysDate); objKey.setDate(calDate); objKey.setScannerId(id); objKey.setStartTime(startTime); GetSummaryRequestType request = getMyServiceObjectFactory().createGetSummaryRequestType(); request.getKeyType().add(objKey); getWebServiceTemplate().setMarshaller(marshaller); getWebServiceTemplate().setUnmarshaller(marshaller); JAXBElement<?> responseElement = null; SoapActionCallback soapActionCallback = new SoapActionCallback("getSummary"); responseElement = (JAXBElement<?>) getWebServiceTemplate().marshalSendAndReceive( request, soapActionCallback); GetSummaryResponseType response = (GetSummaryResponseType)responseElement.getValue(); return response; } catch (Exception e) { log.info("Error: " + e); throw new Exception("My Service is unavailable while fetching the summary information", e); } } }
build.gradle(JAXB/Jakarta相关依赖)
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.1' implementation 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.1' implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.4' implementation 'jakarta.jws:jakarta.jws-api:3.0.0' implementation 'javax.xml.bind:jaxb-api:2.3.1' implementation 'com.sun.xml.bind:jaxb-impl:2.3.4' implementation 'com.sun.xml.ws:jaxws-tools:4.0.2' implementation 'one.gfw:jakarta.activation-api:2.1.1'
排查方向与解决办法
1. SOAP Action参数不匹配
大部分SOAP服务要求完整命名空间+方法名作为SOAP Action值,而非简单的方法名。当前代码中传入的是"getSummary",需对照SoapUI中的请求配置,替换为完整的SOAP Action值(比如"http://mytest.com/webservice/getSummary")。
修改示例:
// 替换为SoapUI中实际使用的SOAP Action SoapActionCallback soapActionCallback = new SoapActionCallback("http://mytest.com/webservice/getSummary");
2. 服务URL存在拼写或格式问题
确认soapws.url配置与SoapUI中使用的URL完全一致,注意以下细节:
- 大小写是否匹配(部分服务器路径区分大小写)
- 末尾是否多/少斜杠(比如
http://localhost/soapService和http://localhost/soapService/可能被视为不同路径) - 是否遗漏服务端要求的路径后缀
3. 清理依赖冲突
当前依赖中同时引入了JAXB的旧版javax依赖和新版Jakarta依赖,存在版本冲突,可能导致请求格式异常或传输逻辑错误。修改依赖如下:
// 保留Jakarta EE规范的依赖,移除旧版javax依赖 implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.1' implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.4' implementation 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.1' implementation 'jakarta.jws:jakarta.jws-api:3.0.0' // 使用官方Jakarta Activation依赖,替换第三方包 implementation 'jakarta.activation:jakarta.activation-api:2.1.1' // 仅需代码生成时保留,否则可删除 implementation 'com.sun.xml.ws:jaxws-tools:4.0.2'
4. 优化WebServiceTemplate配置
无需在每次调用时手动设置Marshaller/Unmarshaller,可通过构造方法注入时统一配置,避免重复操作可能引发的问题:
@Autowired public MyService(@Qualifier("myMarshaller") Jaxb2Marshaller marshaller, @Value("${soapws.url:http://localhost/soapService}") String wsUrl) { setMarshaller(marshaller); setUnmarshaller(marshaller); setDefaultUri(wsUrl); }
同时删除getSummary方法中的以下代码:
this.setDefaultUri(wsUrl); getWebServiceTemplate().setMarshaller(marshaller); getWebServiceTemplate().setUnmarshaller(marshaller);
5. 开启请求日志排查细节
添加日志配置,查看实际发送的请求URL、SOAP头和请求体,对比SoapUI的请求内容,定位差异:
# application.properties logging.level.org.springframework.ws.client.MessageTracing=TRACE logging.level.org.springframework.ws.server.MessageTracing=TRACE
内容的提问来源于stack exchange,提问作者lank81
相关产品推荐
相关产品推荐

