Spring Boot调用SOAP服务返回null SoapUI测试正常问题求助
问题场景
使用Java + Spring + maven-jaxb2-plugin实现SOAP服务调用,相同参数在SoapUI中可正常返回数据,代码调用返回所有字段为null,已确认代码中参数变量已正常赋值。
相关代码
控制器代码:
import java.sql.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.example.consumingwebservice.wsdl.TransferenciaDocumentos; import com.example.consumingwebservice.wsdl.TransferenciaDocumentosRequest; import com.example.consumingwebservice.wsdl.TransferenciaDocumentosResponse; import client.TransferenciaDocumentosClient; @SpringBootApplication @RestController public class AzurianWsApplication { @Autowired private TransferenciaDocumentosClient client; @GetMapping("/getDocumentos") public TransferenciaDocumentosResponse invokeDocumentosResponse () { TransferenciaDocumentos documentos = new TransferenciaDocumentos(); TransferenciaDocumentosRequest request = new TransferenciaDocumentosRequest(); request.setFechaDesde(Date.valueOf("2021-10-01")); request.setFechaDesde(Date.valueOf("2021-12-31")); request.setNroResolucion(0); request.setRutEmpresa(7656066); request.setWsApiKey("60fa6eb48c91c4e704a4d9c22c19ee"); documentos.setRequest(request); return client.transferenciaDocumentosResponse(documentos); } public static void main(String[] args) { SpringApplication.run(AzurianWsApplication.class, args); } }
客户端代码:
package cl.nobelti.grupogtd.azuriantoax.client; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import com.example.consumingwebservice.wsdl.TransferenciaDocumentos; import com.example.consumingwebservice.wsdl.TransferenciaDocumentosResponse; public class TransferenciaDocumentosClient extends WebServiceGatewaySupport{ public TransferenciaDocumentosResponse transferenciaDocumentosResponse(TransferenciaDocumentos request) { TransferenciaDocumentosResponse response = (TransferenciaDocumentosResponse) getWebServiceTemplate() .marshalSendAndReceive("http://soa.group.com:7503/serviciorecepcion?wsdl", request); return response; } }
返回结果:
{ "transferenciaDocumentosReturn": { "codigoRespuesta": null, "descripcion": null, "documentos": null } }
参考实现文档:
https://spring.io/guides/gs/consuming-web-service/
修复方案
按优先级逐个排查:
- 先改代码笔误:控制器里连续两次调用
setFechaDesde,第一次设置的2021-10-01被第二次的2021-12-31直接覆盖,结束日期fechaHasta根本没赋值,传了null给服务端。不少SOAP服务遇到参数非法不会主动抛错,直接返回空结果,把第二个setter改成request.setFechaHasta(Date.valueOf("2021-12-31"))。 - 修正请求地址:
marshalSendAndReceive不能传带?wsdl的元数据地址,这个地址是用来拿服务描述文档的,不是处理业务请求的端点。打开WSDL文件找soap:address节点的location属性,用那个实际服务地址替换现有URL。 - 加报文日志对比结构:给WebServiceTemplate加SOAP报文日志拦截器,把代码发出去的完整请求报文、收到的响应报文全打印出来,和SoapUI里跑通的报文逐行对比,重点看XML命名空间、节点名称、参数层级是不是完全一致。maven-jaxb2-plugin生成类时如果命名空间配置错,会出现序列化后的XML节点不符合服务端要求,服务端解析不到参数就返回空。
日志拦截器配置参考:@Bean public TransferenciaDocumentosClient transferenciaDocumentosClient(Jaxb2Marshaller marshaller) { TransferenciaDocumentosClient client = new TransferenciaDocumentosClient(); // 这里填WSDL里拿到的实际服务端点地址 client.setDefaultUri("http://soa.group.com:7503/serviciorecepcion"); client.setMarshaller(marshaller); client.setUnmarshaller(marshaller); // 打印全量报文的拦截器 ClientInterceptor[] interceptors = new ClientInterceptor[]{new SoapEnvelopeLoggingInterceptor()}; client.setInterceptors(interceptors); return client; } - 检查JAXB配置:确认
Jaxb2Marshaller的contextPath配置和jaxb2插件生成的Java类包路径完全一致,路径不对会导致反序列化时读不到响应字段,看起来全是null。
内容的提问来源于stack exchange,提问作者anonimo
相关产品推荐
相关产品推荐

