使用JAX-WS跟踪XML请求/响应

209

有没有一种简单的方法(即不使用代理)可以获取使用JAX-WS参考实现(包含在JDK 1.5及更高版本中)发布的Web服务的原始请求/响应XML?

我需要通过代码来实现这一点。

只需通过 clever logging 配置将其记录到文件中就可以了,但这样做可能不够好。

我知道存在其他更复杂和完整的框架,可以完成此任务,但我想保持尽可能简单,而axis、cxf等都会增加相当大的开销,我希望避免这种情况。

谢谢!


6
注意:JAX-WS是一个标准,CXF实现了这个标准。 - Bozho
设置Java系统属性和环境变量,请参见:<br> https://dev59.com/fmw05IYBdhLWcg3wwEUS - DaveX
20个回答

2
使用logback.xml配置文件,您可以执行以下操作:
<logger name="com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe" level="trace" additivity="false">
    <appender-ref ref="STDOUT"/>
</logger>

这将记录请求和响应,如下所示(取决于日志输出的配置):

最初的回答:

09:50:23.266 [qtp1068445309-21] DEBUG c.s.x.i.w.t.h.c.HttpTransportPipe - ---[HTTP request - http://xyz:8081/xyz.svc]---
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="http://xyz.Web.Services/IServiceBase/GetAccessTicket"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
<?xml version="1.0" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">[CONTENT REMOVED]</S:Envelope>--------------------

09:50:23.312 [qtp1068445309-21] DEBUG c.s.x.i.w.t.h.c.HttpTransportPipe - ---[HTTP response - http://xyz:8081/xyz.svc - 200]---
null: HTTP/1.1 200 OK
Content-Length: 792
Content-Type: application/soap+xml; charset=utf-8
Date: Tue, 12 Feb 2019 14:50:23 GMT
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">[CONTENT REMOVED]</s:Envelope>--------------------

我正在尝试找到一种方法,如何在logback中记录此内容,但这对我没有起作用(我尝试了所有系统属性的组合,但日志仍然记录为标准输出)。您的记录器是trace,而日志是debug。您能否请发布整个logback-spring.xml文件? - Pivoman

1

我理解得对吗?你想改变/访问原始的XML消息?

如果是这样的话,你(或者说因为这已经是五年之前的事情了,下一个人)可能需要看一看JAXWS中的Provider接口。客户端的对应部分是使用“Dispatch”类完成的。无论如何,你不必添加处理程序或拦截器。当然,你仍然可以这样做。缺点在于,这种方式下,你完全负责构建SOAPMessage,但它很容易,并且如果这正是你想要的(就像我一样),那么这是完美的。

以下是服务器端的示例(有点笨拙,只是为了实验)-

@WebServiceProvider(portName="Provider1Port",serviceName="Provider1",targetNamespace = "http://localhost:8123/SoapContext/SoapPort1")
@ServiceMode(value=Service.Mode.MESSAGE)
public class Provider1 implements Provider<SOAPMessage>
{
  public Provider1()
  {
  }

  public SOAPMessage invoke(SOAPMessage request)
  { try{


        File log= new File("/home/aneeshb/practiceinapachecxf/log.txt");//creates file object
        FileWriter fw=new FileWriter(log);//creates filewriter and actually creates file on disk

            fw.write("Provider has been invoked");
            fw.write("This is the request"+request.getSOAPBody().getTextContent());

      MessageFactory mf = MessageFactory.newInstance();
      SOAPFactory sf = SOAPFactory.newInstance();

      SOAPMessage response = mf.createMessage();
      SOAPBody respBody = response.getSOAPBody();
      Name bodyName = sf.createName("Provider1Insertedmainbody");
      respBody.addBodyElement(bodyName);
      SOAPElement respContent = respBody.addChildElement("provider1");
      respContent.setValue("123.00");
      response.saveChanges();
      fw.write("This is the response"+response.getSOAPBody().getTextContent());
      fw.close();
      return response;}catch(Exception e){return request;}


   }
}

你像发布SEI一样发布它。
public class ServerJSFB {

    protected ServerJSFB() throws Exception {
        System.out.println("Starting Server");
        System.out.println("Starting SoapService1");

        Object implementor = new Provider1();//create implementor
        String address = "http://localhost:8123/SoapContext/SoapPort1";

        JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();//create serverfactorybean

        svrFactory.setAddress(address);
        svrFactory.setServiceBean(implementor);

        svrFactory.create();//create the server. equivalent to publishing the endpoint
        System.out.println("Starting SoapService1");
  }

public static void main(String args[]) throws Exception {
    new ServerJSFB();
    System.out.println("Server ready...");

    Thread.sleep(10 * 60 * 1000);
    System.out.println("Server exiting");
    System.exit(0);
}
}

或者您可以使用一个Endpoint类来实现。希望这对您有帮助。

如果您将服务模式更改为PAYLOAD(您只会得到Soap Body),您不需要处理头文件等内容。


1
在运行时,您可以简单地执行以下操作:

com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true

作为一个公共变量,dump 在类中被定义如下。
public static boolean dump;

对我来说,使用com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true; 进行工作。 - userfb

1
你可以尝试在webservice前面放置一个ServletFilter,检查请求和响应进入/返回服务的情况。
虽然你没有特别要求代理,但有时我发现tcptrace足以查看连接上发生的情况。它是一个简单的工具,无需安装,可以显示数据流并且也可以写入文件。

1

我已经试了几天找一些框架库来记录web service soap请求和响应。下面的代码为我解决了这个问题:

System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
        System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true");

0

这个主题中有几个使用SoapHandlers的答案。你应该知道,如果调用writeTo(out),SoapHandlers会修改消息。

调用SOAPMessage的writeTo(out)方法会自动调用saveChanges()方法。因此,消息中所有附加的MTOM/XOP二进制数据都会丢失。

我不确定为什么会发生这种情况,但似乎这是一个已记录的特性。

此外,此方法标记了从所有组成AttachmentPart对象的数据被拉入消息的点。

https://docs.oracle.com/javase/7/docs/api/javax/xml/soap/SOAPMessage.html#saveChanges()


0
一种方法是不使用你的代码,而是使用网络数据包嗅探器,如Etheral或WireShark,它们可以捕获带有XML消息作为有效负载的HTTP数据包,并且你可以将它们记录到文件中。
但更复杂的方法是编写自己的消息处理程序。你可以在这里查看这里

0

实际上,如果您查看HttpClientTransport的源代码,您会注意到它还将消息写入java.util.logging.Logger中。这意味着您也可以在日志中看到这些消息。

例如,如果您正在使用Log4J2,则只需要执行以下操作:

  • 将JUL-Log4J2桥接添加到您的类路径中
  • 为com.sun.xml.internal.ws.transport.http.client包设置TRACE级别。
  • 将-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager系统属性添加到您的应用程序启动命令行中

完成这些步骤后,您就可以在日志中看到SOAP消息了。


0

Glassfish/Payara的解决方案

将以下条目添加到记录器设置中(日志级别为FINER):

  • com.sun.xml.ws.transport.http.client.HttpTransportPipe
  • com.sun.xml.ws.transport.http.HttpAdapter

在这里发现此处


0
如果您正在运行IBM Liberty应用服务器,只需将ibm-ws-bnd.xml添加到WEB-INF目录中即可。
<?xml version="1.0" encoding="UTF-8"?>
<webservices-bnd
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ws-bnd_1_0.xsd"
    version="1.0">
    <webservice-endpoint-properties
        enableLoggingInOutInterceptor="true" />
</webservices-bnd>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接