JAX-WS로 XML 요청 / 응답 추적


172

JAX-WS 참조 구현 (JDK 1.5 이상에 포함 된)으로 게시 된 웹 서비스에 대한 원시 요청 / 응답 XML에 액세스하는 쉬운 방법 (일명 프록시 사용 안 함)이 있습니까? 코드를 통해이를 수행 할 수 있어야합니다. 영리한 로깅 구성으로 파일에 기록하는 것만으로도 충분할 것입니다.

나는 그렇게 할 수있는 더 복잡하고 완전한 다른 프레임 워크가 존재한다는 것을 알고 있지만 가능한 한 간단하게 유지하고 싶습니다. 축, cxf 등은 모두 피하고 싶은 상당한 오버 헤드를 추가합니다.

감사!


5
참고 사항 : JAX-WS는 CXF가 구현하는 표준입니다.
Bozho 2009

Java 시스템 특성 및 환경 변수 설정은 다음을 참조하십시오. <br> stackoverflow.com/questions/7054972/…
Dafka

답변:


282

다음 옵션을 사용하면 콘솔에 대한 모든 통신을 로깅 할 수 있습니다 (기술적으로는이 중 하나만 필요하지만 사용하는 라이브러리에 따라 다르므로 4 개를 모두 설정하는 것이 더 안전한 옵션입니다). 예를 들어 코드에서 또는 -D를 사용하는 명령 줄 매개 변수 또는 Upendra가 작성한 환경 변수로 설정할 수 있습니다.

System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.internal.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.HttpAdapter.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999");

자세한 내용은 오류 발생시 JAX-WS로 XML 요청 / 응답 추적 질문 을 참조하십시오.


7
감사합니다. 이것이이 문제에 대한 최상의 답변입니다.
M Smith

5
CLIENT가 Tomcat에서 실행될 때 이것은 작동하지 않습니다. -D 만 작동합니다. 이것이 Tomcat의 classLoader 구조 때문이라고 생각합니까?
Rop

3
System.setProperty ( "com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); JDK7에 번들로 제공되고 기본적으로 사용되는 JAX-WS 2.2 RI에 적합한 것
Glenn Bech

1
tomcat에서이 작업을하려면 catalina.sh의 JAVA_OPTS에 다음 명령을 추가해야합니다. 예를 들어 첫 번째 행에 다음을 추가하십시오. sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump = true -Dcom.sun.xml.internal.ws.transport. http.HttpAdapter.dump = true "이후에는 catalina.out을 확인할 수 있으며이 결과가 표시됩니다.
Reece

4
또한 System.setProperty ( "com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999")를 추가하십시오. 요청 및 응답 출력이 잘리지
않도록

84

다음은 원시 코드의 솔루션입니다 (stjohnroe 및 Shamik 덕분에 함께 제공).

Endpoint ep = Endpoint.create(new WebserviceImpl());
List<Handler> handlerChain = ep.getBinding().getHandlerChain();
handlerChain.add(new SOAPLoggingHandler());
ep.getBinding().setHandlerChain(handlerChain);
ep.publish(publishURL);

SOAPLoggingHandler가있는 곳 (링크 된 예제에서 추출) :

package com.myfirm.util.logging.ws;

import java.io.PrintStream;
import java.util.Map;
import java.util.Set;

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;

/*
 * This simple SOAPHandler will output the contents of incoming
 * and outgoing messages.
 */
public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {

    // change this to redirect output if desired
    private static PrintStream out = System.out;

    public Set<QName> getHeaders() {
        return null;
    }

    public boolean handleMessage(SOAPMessageContext smc) {
        logToSystemOut(smc);
        return true;
    }

    public boolean handleFault(SOAPMessageContext smc) {
        logToSystemOut(smc);
        return true;
    }

    // nothing to clean up
    public void close(MessageContext messageContext) {
    }

    /*
     * Check the MESSAGE_OUTBOUND_PROPERTY in the context
     * to see if this is an outgoing or incoming message.
     * Write a brief message to the print stream and
     * output the message. The writeTo() method can throw
     * SOAPException or IOException
     */
    private void logToSystemOut(SOAPMessageContext smc) {
        Boolean outboundProperty = (Boolean)
            smc.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty.booleanValue()) {
            out.println("\nOutbound message:");
        } else {
            out.println("\nInbound message:");
        }

        SOAPMessage message = smc.getMessage();
        try {
            message.writeTo(out);
            out.println("");   // just to add a newline
        } catch (Exception e) {
            out.println("Exception in handler: " + e);
        }
    }
}

8
위의 코드로 응답 / 요청 XML이 여전히 표시되지 않으면 링크를 참조하십시오. stackoverflow.com/questions/2808544/…
ian_scho

2
이것은 SOAPMessage 객체의 존재에 의존하기 때문에 서버로부터 잘못된 응답을 받으면 실패합니다 (예외는 인쇄하지만 추적은 인쇄하지 않음). 징조가 잘못되었을 때에도 추적이 필요한 경우 내 대답을 확인하십시오.
Mr. Napik

맨 위의 스 니펫에서 : 마지막 줄에 관하여 ep.publish(publishURL);: 무엇입니까 publishURL(내 코드에서 wsdl URL은 서비스 자체에 포함되어 있습니다. 외부에 URL이 없습니다. 무엇을 놓치나요?)
badera

모든 인터페이스에 게시하려면 publishUrl은 다음과 같습니다 (hltp = http) : "hltp : //0.0.0.0 : 8080 / standalone / service". 이 경우 "hltp : //127.0.0.1 : 8080 / standalone / service / yourService"에서 서비스에 액세스 할 수 있습니다. 여기서 "yourService"는 wsdl에 정의 된 wsdl 포트 위치입니다.
riskop 2016 년

@ Mr.Napik : 그러나이 방법으로 여전히 로깅 기능을 제공 할 수 있으므로 로깅 프레임 워크를 사용할 때 좋습니다.
Daniel

54

Tomcat을 시작하기 전에 JAVA_OPTSLinux 환경에서 아래와 같이 설정 하십시오. 그런 다음 Tomcat을 시작하십시오. catalina.out파일 에 요청 및 응답이 표시 됩니다.

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"

3
훌륭한. 이것이 IMHO의 가장 좋은 답변입니다.
Pablo Santa Cruz

어떤 이유로, 나를 위해 그것은 :-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
tibo

어떤 이유로 든 이것은 3 개의 웹 서비스 중 하나에서만 작동했습니다 (Tomcat 웹 응용 프로그램에는 3 개의 JAX-WS 웹 서비스가 있습니다). 왜 모든 3에서 작동하지 않는지 알고 있습니까?
David Brossard

테스트가 실패한 이유를 알기 위해 잘 작동했습니다 (테스트의 '구성 실행'에서 'VM 인수'로 옵션 설정).
MrSmith42

당신은 이제까지 가장 좋은 대답와 인터넷을 exploeded 폐하
vikingsteve

16

다음 시스템 속성을 설정하면 XML 로깅이 활성화됩니다. Java 또는 구성 파일에서 설정할 수 있습니다.

static{
        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");
        System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999");
    }

콘솔 로그 :

INFO: Outbound Message
---------------------------
ID: 1
Address: http://localhost:7001/arm-war/castService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: xml
--------------------------------------
INFO: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml; charset=UTF-8
Headers: {content-type=[text/xml; charset=UTF-8], Date=[Fri, 20 Jan 2017 11:30:48 GMT], transfer-encoding=[chunked]}
Payload: xml
--------------------------------------

14

SOAPHandler엔드 포인트 인터페이스에 주입하십시오 . SOAP 요청과 응답을 추적 할 수 있습니다

프로그래밍 방식으로 SOAPHandler 구현

ServerImplService service = new ServerImplService();
Server port = imgService.getServerImplPort();
/**********for tracing xml inbound and outbound******************************/
Binding binding = ((BindingProvider)port).getBinding();
List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(new SOAPLoggingHandler());
binding.setHandlerChain(handlerChain);

@HandlerChain(file = "handlers.xml")엔드 포인트 인터페이스에 주석을 추가하여 선언적 입니다.

handlers.xml

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
        <handler>
            <handler-class>SOAPLoggingHandler</handler-class>
        </handler>
    </handler-chain>
</handler-chains>

SOAPLoggingHandler.java

/*
 * This simple SOAPHandler will output the contents of incoming
 * and outgoing messages.
 */


public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
    public Set<QName> getHeaders() {
        return null;
    }

    public boolean handleMessage(SOAPMessageContext context) {
        Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (isRequest) {
            System.out.println("is Request");
        } else {
            System.out.println("is Response");
        }
        SOAPMessage message = context.getMessage();
        try {
            SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
            SOAPHeader header = envelope.getHeader();
            message.writeTo(System.out);
        } catch (SOAPException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    public boolean handleFault(SOAPMessageContext smc) {
        return true;
    }

    // nothing to clean up
    public void close(MessageContext messageContext) {
    }

}

나는 이것을 정확하게 따르고 있습니다. 헤더를 수정 한 후 메시지를 인쇄하지만 해당 변경 사항이 표시되지 않습니다. 메시지는 handleMessage 방법 잎 때까지 변경되지 않는 것처럼 나타납니다
Iofacture

메시지를 두 번 인쇄하기 위해 전화하면 두 번째로 업데이트됩니다. 매우 이상합니다
Iofacture

11

다른 답변에서 설명한 것처럼 프로그래밍 방식 으로이 작업을 수행하는 다양한 방법이 있지만 상당히 침습적 인 메커니즘입니다. 그러나 JAX-WS RI (일명 "Metro")를 사용중인 경우 구성 레벨에서이를 수행 할 수 있습니다. 이 작업을 수행하는 방법에 대한 지침은 여기를 참조하십시오 . 응용 프로그램을 망칠 필요가 없습니다.


2
메트로 = JAX-WS RI + WSIT (즉, JAX-WS RI! = 메트로)
Pascal Thivent

@Pau : 고정. 저에게 투표를하는 대신 약간의 노력을 기울이고 대안적인 링크를 제안 할 수 있습니다.
skaffman

1
내가 찾은 경우 넣어 두 었는지 확인하십시오. 개인적으로 받아들이지 마십시오. 삭제 투표;)
Pau

링크가 다시 끊어졌습니다 (java.net은 어떻게됩니까 ???). 나는 이것이 새로운 링크라고 생각한다 : metro.java.net/nonav/1.2/guide/Logging.html
sdoca

9

//이 솔루션은 XML 설정없이 웹 서비스 clien에 핸들러를 프로그래밍 방식으로 추가하는 방법을 제공합니다.

// 여기에서 전체 문서를 참조하십시오 : http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htm#i222476

// SOAPHandler를 구현하는 새 클래스를 만듭니다.

public class LogMessageHandler implements SOAPHandler<SOAPMessageContext> {

@Override
public Set<QName> getHeaders() {
    return Collections.EMPTY_SET;
}

@Override
public boolean handleMessage(SOAPMessageContext context) {
    SOAPMessage msg = context.getMessage(); //Line 1
    try {
        msg.writeTo(System.out);  //Line 3
    } catch (Exception ex) {
        Logger.getLogger(LogMessageHandler.class.getName()).log(Level.SEVERE, null, ex);
    } 
    return true;
}

@Override
public boolean handleFault(SOAPMessageContext context) {
    return true;
}

@Override
public void close(MessageContext context) {
}
}

// 프로그래밍 방식으로 LogMessageHandler 추가

   com.csd.Service service = null;
    URL url = new URL("https://service.demo.com/ResService.svc?wsdl");

    service = new com.csd.Service(url);

    com.csd.IService port = service.getBasicHttpBindingIService();
    BindingProvider bindingProvider = (BindingProvider)port;
    Binding binding = bindingProvider.getBinding();
    List<Handler> handlerChain = binding.getHandlerChain();
    handlerChain.add(new LogMessageHandler());
    binding.setHandlerChain(handlerChain);

4

Antonio가 제공 한 답변에 대해 언급 할만 큼 평판이 충분하지 않으므로 새 답변을 게시하고 있습니다 ( https://stackoverflow.com/a/1957777 참조 ).

SOAP 메시지를 파일에 인쇄하려면 (예 : Log4j를 통해) 다음을 사용할 수 있습니다.

OutputStream os = new ByteArrayOutputStream();
javax.xml.soap.SOAPMessage soapMsg = context.getMessage();
soapMsg.writeTo(os);
Logger LOG = Logger.getLogger(SOAPLoggingHandler.class); // Assuming SOAPLoggingHandler is the class name
LOG.info(os.toString());

특정 상황에서 메소드 호출 writeTo ()가 예상대로 작동하지 않을 수 있습니다 ( https://community.oracle.com/thread/1123104?tstart=0 또는 https://www.java.net/node 참조). / 691073 ), 다음 코드는 트릭을 수행합니다.

javax.xml.soap.SOAPMessage soapMsg = context.getMessage();
com.sun.xml.ws.api.message.Message msg = new com.sun.xml.ws.message.saaj.SAAJMessage(soapMsg);
com.sun.xml.ws.api.message.Packet packet = new com.sun.xml.ws.api.message.Packet(msg);
Logger LOG = Logger.getLogger(SOAPLoggingHandler.class); // Assuming SOAPLoggingHandler is the class name
LOG.info(packet.toString());

2

javax.xml.ws.handler.LogicalHandler를 구현해야하며,이 핸들러는 핸들러 구성 파일에서 참조되어야하며, 이는 서비스 엔드 포인트 (인터페이스 또는 구현)의 @HandlerChain 주석에 의해 참조됩니다. 그런 다음 system.out 또는 processMessage 구현의 로거를 통해 메시지를 출력 할 수 있습니다.

보다

http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/twbs_jaxwshandler.html

http://java.sun.com/mailers/techtips/enterprise/2006/TechTips_June06.html


2

사용을 안내하는 여기에 나열된 답변 SOAPHandler은 완전히 정확합니다. SOAPHandler가 JAX-WS 스펙의 일부이므로이 방법의 이점은 모든 JAX-WS 구현에서 작동한다는 것입니다. 그러나 SOAPHandler의 문제점은 메모리에서 전체 XML 메시지를 암시 적으로 나타내려고 시도한다는 것입니다. 이로 인해 엄청난 메모리 사용이 발생할 수 있습니다. JAX-WS의 다양한 구현은 이에 대한 자체 해결 방법을 추가했습니다. 큰 요청이나 큰 응답으로 작업하는 경우 독점 접근 방식 중 하나를 조사해야합니다.

"JDK 1.5 이상에 포함 된 것"에 대해 질문하므로 JDK에 포함 된 JAX-WS RI (일명 Metro)에 대해 공식적으로 답변하겠습니다.

JAX-WS RI에는 메모리 사용 측면에서 매우 효율적인 특정 솔루션이 있습니다.

https://javaee.github.io/metro/doc/user-guide/ch02.html#efficient-handlers-in-jax-ws-ri를 참조 하십시오 . 불행히도이 링크는 끊어졌지만 WayBack Machine에서 찾을 수 있습니다. 아래에서 주요 내용을 알려 드리겠습니다.

2007 년 메트로 사람들은 Metro 에 독점적 인 추가 핸들러 유형을 도입 했습니다 MessageHandler<MessageHandlerContext>. SOAPHandler<SOAPMessageContext>인 메모리 DOM 표현을 시도하지 않는 것보다 훨씬 효율적 입니다.

원본 블로그 기사의 중요한 내용은 다음과 같습니다.

MessageHandler :

JAX-WS Specification에서 제공하는 확장 가능한 처리기 프레임 워크와 RI의 향상된 메시지 추상화를 활용 MessageHandler하여 웹 서비스 응용 프로그램을 확장 하는 새로운 처리기를 도입했습니다 . MessageHandler는 SOAPHandler와 유사하지만 구현시 액세스가 가능하다는 점만 다릅니다.MessageHandlerContext(MessageContext의 확장). MessageHandlerContext를 통해 Message API를 사용하여 Message에 액세스하고 처리 할 수 ​​있습니다. 블로그 제목에 넣을 때이 핸들러를 사용하면 DOM 기반 메시지뿐만 아니라 메시지를 효율적으로 액세스 / 처리 할 수있는 메시지 작업을 수행 할 수 있습니다. 핸들러의 프로그래밍 모델은 동일하며 메시지 핸들러는 표준 논리 및 SOAP 핸들러와 혼합 될 수 있습니다. JAX-WS RI 2.1.3에 MessageHandler를 사용하여 메시지를 로그하는 샘플을 추가했으며 다음은 샘플의 스 니펫입니다.

public class LoggingHandler implements MessageHandler<MessageHandlerContext> {
    public boolean handleMessage(MessageHandlerContext mhc) {
        Message m = mhc.getMessage().copy();
        XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out);
        try {
            m.writeTo(writer);
        } catch (XMLStreamException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean handleFault(MessageHandlerContext mhc) {
        ..... 
        return true;
    }

    public void close(MessageContext messageContext) {    }

    public Set getHeaders() {
        return null;
    }
}

(2007 블로그 게시물에서 인용문 끝)

LoggingHandler이 예제에서 사용자 지정 처리기 를 처리기 체인에 추가해야 효과를 얻을 수 있습니다. 이것은 other를 추가하는 것과 동일 하므로이 페이지 Handler다른 답변 에서 방법을 찾을 수 있습니다.

Metro GitHub 리포지토리 에서 전체 예제 를 찾을 수 있습니다 .


1

ServletFilter웹 서비스 앞에 넣고 서비스에서 / 요청으로 이동하는 요청 및 응답을 검사 하려고 시도 할 수 있습니다.

프록시를 요청하지 않았지만 tcptrace 가 연결에서 무슨 일이 일어나는지 알기 에 충분합니다. 간단한 도구이며 설치가 필요 없으며 데이터 스트림을 표시하고 파일에도 쓸 수 있습니다.


1

에서 런타임 간단히 실행할 수 있습니다

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

덤프는 다음과 같이 클래스에 정의 된 속성 public var이다

public static boolean dump;

나를 위해 com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true;
userfb

1

원시 XML 메시지를 변경 / 액세스하려는 것으로 이해하고 있습니까?

그렇다면, 귀하 (또는이 사람이 5 세이므로 다음 사람)는 JAXWS의 일부인 제공자 인터페이스를 살펴볼 수 있습니다. 클라이언트 상대방은 "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로 변경하면 비누 바디 만 얻습니다.


1

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>--------------------

1

웹 서비스 비누 요청 및 응답을 며칠 동안 기록 할 프레임 워크 라이브러리를 찾으려고 노력했습니다. 아래 코드는 나를 위해 문제를 해결했습니다.

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

한 가지 방법은 코드를 사용하지 않고 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

이 스레드에는 SoapHandlers를 사용하여 몇 가지 답변이 있습니다. SoapHandlers writeTo(out)가 호출 되면 메시지를 수정한다는 것을 알아야합니다 .

SOAPMessage의 writeTo(out)메소드를 호출하면 saveChanges()메소드도 자동으로 호출됩니다 . 결과적으로 메시지에 첨부 된 모든 MTOM / XOP 이진 데이터가 손실됩니다.

왜 이런 일이 발생하는지 잘 모르겠지만 문서화 된 기능인 것 같습니다.

또한이 방법은 모든 구성 AttachmentPart 객체의 데이터를 메시지로 가져 오는 지점을 표시합니다.

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


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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.