【问题标题】:Tracing XML request/responses with JAX-WS when error occurs发生错误时使用 JAX-WS 跟踪 XML 请求/响应
【发布时间】:2011-07-18 01:17:15
【问题描述】:

如果有任何错误,我想记录原始的肥皂发布请求,我正在使用 JAX-WS。任何帮助将不胜感激。

是否有一种简单的方法(又名:不使用代理)仅在发生异常时才能访问使用 JAX-WS 参考实现(JDK 1.5 和更好的版本)发布的 Web 服务的原始请求/响应 XML作为回应?我想记录原始 SOAP reuest,以便以后可以通过任何 Web 服务客户端对其进行测试

【问题讨论】:

    标签: java jax-ws


    【解决方案1】:

    可以使用系统属性(这里是 test 任务的 Gradle DSL):

    systemProperty "com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true"
    systemProperty "com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"
    systemProperty "com.sun.xml.ws.transport.http.HttpAdapter.dump", "true"
    systemProperty "com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true"
    systemProperty "com.sun.xml.ws.transport.http.HttpAdapter.dumpTreshold", "99999"
    systemProperty "com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "99999"
    

    但这些设置是全局的,并且可能需要大量启用它们才能在 PROD 上启用...如果您想减少 XML 日志记录的数量,那么将过滤器添加到绑定到业务逻辑的日志记录框架并不有趣。

    在 WS 处理程序中捕获 req/rsp 主体的详细信息在我的回答 How can I pass data back from a SOAP handler to a webservice client?

    这是一个重要的部分:

    public class MsgLogger implements SOAPHandler<SOAPMessageContext> {
    
        public static String REQEST_BODY = "com.evil.request";
        public static String RESPONSE_BODY = "com.evil.response";
    
        @Override
        public Set<QName> getHeaders() {
            return null;
        }
    
        @Override
        public boolean handleMessage(SOAPMessageContext context) {
            SOAPMessage msg = context.getMessage();
            Boolean beforeRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream(32_000);
                context.getMessage().writeTo(baos);
                String key = beforeRequest ? REQEST_BODY : RESPONSE_BODY;
                context.put(key, baos.toString("UTF-8"));
                context.setScope(key, MessageContext.Scope.APPLICATION);
            } catch (SOAPException | IOException e) { }
            return true;
        }
    
        @Override
        public boolean handleFault(SOAPMessageContext context) {
            return handleMessage(context);
        }
    
        @Override
        public void close(MessageContext context) { }
    }
    

    注册处理程序并使用保留的属性:

    BindingProvider provider = (BindingProvider) port;
    List<Handler> handlerChain = provider.getBinding().getHandlerChain();
    handlerChain.add(new MsgLogger());
    provider.getBinding().setHandlerChain(handlerChain);
    
    Req req = ...;
    Rsp rsp = port.serviceCall(req); // call WS Port
    
    // Access saved message bodies:
    Map<String, Object> responseContext = provider.getResponseContext();
    String reqBody = (String) responseContext.get(MsgLogger.REQEST_BODY);
    String rspBody = (String) responseContext.get(MsgLogger.RESPONSE_BODY);
    

    有了这个解决方案(它只是一个框架,正确的错误处理/边缘情况由你决定)你决定稍后在你得到响应时记录。

    【讨论】:

    • 此答案基于 The Java API for XML-Based Web Services (JAX-WS) 2.3 规范,因此适用于任何 JAX WS 实现。
    【解决方案2】:

    只是想我会提到这一点:

    什么时候使用带有internal 的属性名称,什么时候不使用?

    如果您阅读Metro Guide,它会告诉您使用:

    在客户端:

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

    在服务器上:

    com.sun.xml.ws.transport.http.HttpAdapter.dump=true
    

    但是:在我看来,当 JAX-WS RI 库作为标准包含在 JDK 中时(这是 Java 6 的标准),Sun 不得不重命名属性名称以包含“内部”。因此,如果您使用的是与 JDK 捆绑在一起的 JAX-WS RI,那么您必须确保将internal 添加到属性名称中。否则将无法正常工作。换句话说,您需要使用:

    在客户端:

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

    在服务器上:

    com.sun.xml.internal.ws.transport.http.HttpAdapter.dump=true
    

    另一方面,如果您使用的是独立版本的 JAX-WS RI(或作为一个整体的 Metro),那么我猜您应该使用属性名称​​没有internal

    如果有人对此有内幕消息并能说出这是否属实,我会很高兴。

    【讨论】:

      【解决方案3】:

      如果您使用 Jboss 6.1 并且想要将 JAX-WS 生成的类请求的日志打印到 SOAP Web 服务, 打开文件/home/oracle/jboss-eap-6.1/bin/standalone.sh 注意:请到你安装jboss的地方

      你会发现这样的东西

      JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n"
      

      改成如下图

      JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n"
      

      还要确保启用调试

      DEBUG_MODE=true
      

      【讨论】:

        【解决方案4】:

        这对我有用:

        -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
        

        【讨论】:

          【解决方案5】:

          使用

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

          com.sun.xml.internal.ws.transport.http.HttpAdapter.dump=true

          相反(注意包名称中的“内部”),这对我有用。

          干杯, 托斯滕

          【讨论】:

          • 更改了 catalina.sh 文件,包括“内部”但仍然看不到日志/catalina.yyyy-MM-dd.log 文件中的任何更改
          • .internal。当您使用 JRE 中包含的 JAX WS 版本时是必需的,而非“.internal”。当您明确使用 JAX WS 库时,使用版本
          • 如何添加时间戳,特定请求到达服务器的时间以及服务器响应的时间?
          【解决方案6】:

          除了托尔斯滕的回答

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

          确保在实例化 WebServiceClient 对象(扩展服务的对象)之前设置此设置

          【讨论】:

            【解决方案7】:

            我认为您需要的是一个处理程序,请参阅: http://jax-ws.java.net/articles/handlers_introduction.html
            使用处理程序,您可以拦截 Web 服务调用,并可以访问所有 SOAP 消息。

            【讨论】:

              【解决方案8】:

              您可能想尝试的第一件事是使用以下系统属性中的一个或两个:

              客户:

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

              服务器:

              com.sun.xml.ws.transport.http.HttpAdapter.dump=true
              

              【讨论】:

              • 我在我的tomcat服务器的catalina.properties文件中添加了以上属性,但是看不到任何更新的日志,请指教
              • 在 JAVA_OPTS 上添加到我的 catalina.sh 但看不到任何更改
              • 不要更改 catalina.properties。你如何设置JAVA_OPTS?日志应该通过System.out 输出。
              • 以下是我的 catalina.sh 文件中的 JAVA_OPTS 行 JAVA_OPTS="-Dcom.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace = false -Djava.awt.headless=true -Dfile.encoding =UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -Dcom.sun.xml.ws.transport。 http.client.HttpTransportPipe.dump = true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump = true"
              • ...logs/catalina.out 中没有显示任何内容?我想知道您使用的是什么 JDK 和 Tomcat 版本会很好......
              猜你喜欢
              • 2010-12-29
              • 2012-04-02
              • 1970-01-01
              • 1970-01-01
              • 2011-11-10
              • 1970-01-01
              • 1970-01-01
              • 2023-03-14
              • 1970-01-01
              相关资源
              最近更新 更多