请求协助获取发送至SOAP服务的实际请求XML内容
捕获Spring WebServiceTemplate发送的SOAP请求XML
我们的应用通过以下代码调用SOAP服务:
res = (CreateResponse) JAXBIntrospector.getValue(getWebServiceTemplate() .marshalSendAndReceive(soapUrl, req, new headers(msgHeader)));
其中:
soapUrl:目标SOAP服务地址req:CreateRequest类的实例对象msgHeader:MsgHeader类的实例对象
当前调用返回错误:
ns0:MsgErrorCd Description="REQUEST STRUCTURE INVALID"
SOAP服务维护方需要查看实际发送的请求XML内容,以下是几种可行的解决方法:
方法1:添加自定义日志拦截器
利用Spring WS的客户端拦截器机制,在请求发送前打印完整的SOAP XML:
- 编写拦截器类:
import org.springframework.ws.client.support.interceptor.ClientInterceptorAdapter; import org.springframework.ws.context.MessageContext; import org.springframework.ws.soap.SoapMessage; import java.io.ByteArrayOutputStream; import java.io.IOException; public class SoapLoggingInterceptor extends ClientInterceptorAdapter { @Override public boolean handleRequest(MessageContext messageContext) throws IOException { SoapMessage soapReq = (SoapMessage) messageContext.getRequest(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); soapReq.writeTo(outputStream); String reqXml = outputStream.toString("UTF-8"); // 直接打印到控制台或写入日志文件 System.out.println("发送的SOAP请求:\n" + reqXml); return true; } }
- 给WebServiceTemplate注册拦截器:
WebServiceTemplate wsTemplate = getWebServiceTemplate(); wsTemplate.setInterceptors(new ClientInterceptor[]{new SoapLoggingInterceptor()});
方法2:开启Spring WS内置日志
通过配置日志框架(如Logback、Log4j2),直接打印框架输出的SOAP请求内容:
在日志配置文件中添加:
<!-- 打印发送的SOAP请求完整内容 --> <logger name="org.springframework.ws.client.MessageTracing.sent" level="TRACE"/> <!-- 若需要查看响应,可同时开启 --> <logger name="org.springframework.ws.client.MessageTracing.received" level="TRACE"/>
注意:必须将日志级别设为TRACE才能输出完整XML,生产环境建议临时开启,避免日志过载。
方法3:手动序列化请求对象
直接用JAXB将请求对象和头信息序列化为XML,快速验证结构是否正确:
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import java.io.StringWriter; public void printRequestXml() throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(CreateRequest.class, MsgHeader.class); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter writer = new StringWriter(); // 先序列化头信息,再序列化请求体 marshaller.marshal(msgHeader, writer); marshaller.marshal(req, writer); String reqXml = writer.toString(); System.out.println("请求对象序列化后的XML:\n" + reqXml); }
这种方式需要手动补充SOAP envelope的外层标签,但可以快速排查对象注解或字段是否符合服务端要求。
内容的提问来源于stack exchange,提问作者F0cus
相关产品推荐
相关产品推荐

