求助:无法记录JAX-WS客户端收发的XML消息
解决Java 8中wsimport生成的SOAP客户端消息追踪问题
我之前也碰到过类似的情况,用wsimport生成的JAX-WS客户端在Java 8里抓SOAP消息确实得注意几个细节,给你梳理几个靠谱的解决方案:
方案1:确保系统属性在客户端初始化前设置
你尝试的那两个系统属性方向是对的,但必须在创建SOAP客户端/端口实例之前设置,否则不会生效。另外要注意,这些属性是Sun/Oracle系JAX-WS实现(也就是你用wsimport生成代码依赖的com.sun.xml.ws)专属的,版本要和wsimport的2.2.9匹配,避免依赖冲突。
正确的代码示例应该是这样:
public class TestClass { public static void main(String[] args) { // 先设置系统属性,再初始化客户端 System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true"); System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true"); // 这里才初始化你的SOAP客户端和端口 YourService service = new YourService(); YourPortType port = service.getYourPort(); // 调用服务方法 port.yourServiceMethod(); } }
方案2:添加自定义SOAP Handler(更稳定可靠)
如果系统属性方式还是没效果,自定义Handler是最稳妥的方法——能直接捕获请求和响应的完整SOAP消息,不受系统配置或依赖版本的影响。
- 先实现一个SOAPHandler:
import javax.xml.namespace.QName; import javax.xml.soap.SOAPMessage; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import java.io.ByteArrayOutputStream; import java.util.Set; public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> { @Override public boolean handleMessage(SOAPMessageContext context) { Boolean isOutbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); try { SOAPMessage soapMsg = context.getMessage(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); soapMsg.writeTo(baos); String msgContent = baos.toString(); if (isOutbound) { System.out.println("=== 发送的SOAP请求 ==="); } else { System.out.println("=== 接收的SOAP响应 ==="); } System.out.println(msgContent); // 允许消息继续流转 return true; } catch (Exception e) { e.printStackTrace(); return false; } } @Override public boolean handleFault(SOAPMessageContext context) { // 可选:捕获SOAP Fault消息并打印 return true; } @Override public void close(MessageContext context) { // 清理资源,无需额外操作 } @Override public Set<QName> getHeaders() { return null; } }
- 将Handler添加到你的客户端端口:
public class TestClass { public static void main(String[] args) { YourService service = new YourService(); YourPortType port = service.getYourPort(); // 通过BindingProvider添加Handler链 BindingProvider bindingProvider = (BindingProvider) port; List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain(); handlerChain.add(new SOAPLoggingHandler()); bindingProvider.getBinding().setHandlerChain(handlerChain); // 调用服务方法 port.yourServiceMethod(); } }
方案3:配置JDK日志系统
你也可以通过修改JDK的日志配置来开启JAX-WS的消息输出:
- 找到Java安装目录下的
jre/lib/logging.properties(或者自定义一个配置文件) - 添加以下配置项:
com.sun.xml.ws.level=FINE java.util.logging.ConsoleHandler.level=FINE java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
- 启动程序时指定这个配置文件:
java -Djava.util.logging.config.file=/path/to/your/logging.properties TestClass
这样JAX-WS会把SOAP消息的详细内容输出到控制台。
内容的提问来源于stack exchange,提问作者davioooh
相关产品推荐
相关产品推荐

