Melacak permintaan / tanggapan XML dengan JAX-WS

172

Apakah ada cara mudah (alias: tidak menggunakan proxy) untuk mendapatkan akses ke permintaan mentah / respons XML untuk layanan web yang diterbitkan dengan implementasi referensi JAX-WS (yang termasuk dalam JDK 1.5 dan lebih baik)? Mampu melakukan itu melalui kode adalah apa yang perlu saya lakukan. Hanya dengan login ke file dengan konfigurasi logging yang cerdik akan lebih baik tetapi cukup.

Saya tahu bahwa ada kerangka kerja lain yang lebih kompleks dan lengkap yang mungkin melakukan itu, tetapi saya ingin membuatnya sesederhana mungkin dan sumbu, cxf, dll semua menambahkan overhead yang cukup besar yang ingin saya hindari.

Terima kasih!

Antonio
sumber
5
Sekedar catatan: JAX-WS adalah standar, yang diterapkan CXF.
Bozho
Mengatur properti sistem Java dan variabel lingkungan lihat: <br> stackoverflow.com/questions/7054972/…
Dafka

Jawaban:

282

Opsi berikut memungkinkan pencatatan semua komunikasi ke konsol (secara teknis, Anda hanya memerlukan satu di antaranya, tetapi itu tergantung pada pustaka yang Anda gunakan, jadi pengaturan keempat adalah pilihan yang lebih aman). Anda dapat mengaturnya dalam kode seperti pada contoh, atau sebagai parameter baris perintah menggunakan -D atau sebagai variabel lingkungan seperti yang ditulis 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");

Lihat pertanyaan Tracing permintaan XML / tanggapan dengan JAX-WS ketika kesalahan terjadi untuk detail.

Pak Napik
sumber
7
Terima kasih, ini adalah jawaban terbaik yang saya temukan untuk masalah ini
M Smith
5
Ini TIDAK bekerja untuk saya, ketika KLIEN berjalan di Tomcat. Hanya hal -D yang bekerja. Saya percaya ini karena struktur classLoader di Tomcat?
Rop
3
System.setProperty ("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); adalah yang tepat untuk JAX-WS 2.2 RI yang dibundel dalam JDK7 dan digunakan secara default
Glenn Bech
1
untuk pekerjaan ini di tomcat Anda perlu menambahkan perintah ini ke JAVA_OPTS di catalina.sh misalnya pada baris pertama tambahkan: JAVA_OPTS = "-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom. 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 "setelah itu Anda dapat memeriksa catalina.out dan output dari ini akan ditampilkan di sana.
Reece
4
Juga tambahkan System.setProperty ("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999"); untuk tidak memiliki permintaan dan respons keluaran terpotong
8bitme
84

Inilah solusi dalam kode mentah (disatukan berkat stjohnroe dan Shamik):

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

Di mana SOAPLoggingHandler berada (disobek dari contoh terkait):

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);
        }
    }
}
Antonio
sumber
8
Lihat tautan jika Anda masih tidak melihat respons / permintaan xml dengan kode di atas: stackoverflow.com/questions/2808544/…
ian_scho
2
Ini bergantung pada keberadaan objek SOAPMessage, sehingga akan gagal (cukup cetak pengecualian, tetapi bukan jejak) jika Anda menerima respons cacat dari server. Periksa jawaban saya, jika Anda perlu melacak bahkan ketika ada yang salah.
Tn. Napik
Dalam cuplikan di atas: mengenai baris terakhir ep.publish(publishURL);: apa itu publishURL(Dalam kode saya, url wsdl termasuk dalam layanan itu sendiri; saya tidak punya url di luar. Apa yang saya lewatkan?)
badera
Jika Anda ingin mempublikasikannya di semua antarmuka maka publishUrl adalah sesuatu seperti ini (hltp = http): "hltp: //0.0.0.0: 8080 / standalone / service". Dalam kasus khusus ini, Anda dapat mengakses layanan di "hltp: //127.0.0.1: 8080 / standalone / service / yourService" di mana "yourService" adalah lokasi port wsdl yang ditentukan dalam wsdl.
riskop
@ Mr.Napik: Tapi dengan cara ini Anda masih bisa menyediakan fasilitas logging Anda sendiri, yang bagus saat Anda menggunakan framework logging.
Daniel
54

Sebelum memulai kucing jantan, atur JAVA_OPTSseperti di bawah ini di Linux envs. Kemudian mulai Tomcat. Anda akan melihat permintaan dan respons dalam catalina.outfile.

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"
Upendra
sumber
3
Cemerlang. Ini adalah jawaban IMHO terbaik.
Pablo Santa Cruz
Untuk beberapa alasan, bagi saya itu adalah:-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
tibo
Untuk beberapa alasan, ini hanya berfungsi pada satu dari 3 layanan web saya (Saya memiliki 3 layanan web JAX-WS di aplikasi web Tomcat saya). Adakah yang tahu mengapa itu tidak bekerja pada ketiga?
David Brossard
Bekerja dengan baik bagi saya untuk melihat mengapa pengujian saya gagal (Tetapkan opsi di 'jalankan konfigurasi' pengujian saya sebagai 'argumen VM').
MrSmith42
Anda baru saja mengeksploitasi internet dengan jawaban terbaik yang pernah ada
vikingsteve
16

Setel properti sistem berikut, ini akan mengaktifkan logging xml. Anda dapat mengaturnya di java atau file konfigurasi.

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");
    }

log konsol:

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
--------------------------------------
2787184
sumber
14

Suntikkan SOAPHandlerke antarmuka titik akhir. kita dapat melacak permintaan dan respons SOAP

Menerapkan SOAPHandler dengan Programmatic

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

Deklaratif dengan menambahkan @HandlerChain(file = "handlers.xml")anotasi ke antarmuka titik akhir Anda.

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) {
    }

}
Premraj
sumber
Saya mengikuti ini persis. Saya mencetak pesan setelah melakukan modifikasi pada tajuk, namun saya tidak melihat perubahan itu. Tampaknya seolah-olah pesan tidak berubah sampai setelah meninggalkan metode
handleMessage
Jika saya memanggil untuk mencetak pesan dua kali, kedua kalinya ada pembaruan. Sangat aneh
Iofacture
11

Ada berbagai cara untuk melakukan ini secara terprogram, seperti dijelaskan dalam jawaban lain, tetapi mereka merupakan mekanisme yang cukup invasif. Namun, jika Anda tahu bahwa Anda menggunakan JAX-WS RI (alias "Metro"), maka Anda dapat melakukan ini di tingkat konfigurasi. Lihat di sini untuk instruksi tentang cara melakukan ini. Tidak perlu dipusingkan dengan aplikasi Anda.

skaffman
sumber
2
Metro = JAX-WS RI + WSIT (yaitu JAX-WS RI! = Metro)
Pascal Thivent
@ Ping: Tetap. Anda tahu, daripada memilih saya untuk itu, Anda bisa melakukan sedikit usaha dan menyarankan tautan alternatif.
skaffman
1
Jika saya menemukan satu, pastikan saya akan meletakkannya. Jangan menganggapnya sebagai masalah pribadi. dihapus suara;)
Pau
Tautan rusak lagi (ada apa dengan java.net ???). Saya pikir ini adalah tautan baru: metro.java.net/nonav/1.2/guide/Logging.html
sdoca
9

// Solusi ini menyediakan cara menambahkan pemandu ke pemrograman web secara terprogram tanpa konfigurasi XML

// Lihat dokumen lengkap di sini: http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htm#i222476

// Buat kelas baru yang mengimplementasikan 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) {
}
}

// Secara sistematis tambahkan LogMessageHandler Anda

   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);
TriMix
sumber
4

Saya memposting jawaban baru, karena saya tidak memiliki reputasi yang cukup untuk mengomentari jawaban yang diberikan oleh Antonio (lihat: https://stackoverflow.com/a/1957777 ).

Jika Anda ingin pesan SOAP dicetak dalam file (mis. Via Log4j), Anda dapat menggunakan:

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());

Harap dicatat bahwa dalam keadaan tertentu, metode panggilan writeTo () mungkin tidak berperilaku seperti yang diharapkan (lihat: https://community.oracle.com/thread/1123104?tstart=0 atau https://www.java.net/node / 691073 ), oleh karena itu kode berikut akan melakukan trik:

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());
Alex
sumber
2

Anda perlu menerapkan javax.xml.ws.handler.LogicalHandler, pawang ini kemudian perlu direferensikan dalam file konfigurasi handler, yang pada gilirannya dirujuk oleh anotasi @HandlerChain di titik akhir layanan Anda (antarmuka atau implementasi). Anda kemudian dapat menampilkan pesan melalui system.out atau logger dalam implementasi processMessage Anda.

Lihat

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

stjohnroe
sumber
2

Jawaban yang tercantum di sini yang memandu Anda untuk menggunakan SOAPHandlersepenuhnya benar. Manfaat dari pendekatan itu adalah bahwa ia akan bekerja dengan implementasi JAX-WS, karena SOAPHandler adalah bagian dari spesifikasi JAX-WS. Namun, masalah dengan SOAPHandler adalah bahwa ia secara implisit berusaha untuk mewakili seluruh pesan XML dalam memori. Ini dapat menyebabkan penggunaan memori yang sangat besar. Berbagai implementasi JAX-WS telah menambahkan solusi mereka sendiri untuk ini. Jika Anda bekerja dengan permintaan besar atau respons besar, maka Anda perlu melihat ke salah satu pendekatan kepemilikan.

Karena Anda bertanya tentang "yang termasuk dalam JDK 1.5 atau lebih baik" saya akan menjawab sehubungan dengan apa yang secara resmi dikenal sebagai JAX-WS RI (alias Metro) yang merupakan apa yang disertakan dengan JDK.

JAX-WS RI memiliki solusi spesifik untuk ini yang sangat efisien dalam hal penggunaan memori.

Lihat https://javaee.github.io/metro/doc/user-guide/ch02.html#fficiency-handlers-in-jax-ws-ri . Sayangnya tautan itu sekarang rusak tetapi Anda dapat menemukannya di WayBack Machine. Saya akan memberikan highlight di bawah ini:

Orang-orang Metro pada tahun 2007 memperkenalkan jenis penangan tambahan MessageHandler<MessageHandlerContext>, yang merupakan hak milik Metro. Ini jauh lebih efisien daripada SOAPHandler<SOAPMessageContext>karena tidak mencoba melakukan representasi DOM dalam memori.

Inilah teks penting dari artikel blog asli:

MessageHandler:

Memanfaatkan kerangka Handler yang dapat diperluas yang disediakan oleh Spesifikasi JAX-WS dan abstraksi Pesan yang lebih baik di RI, kami memperkenalkan penangan baru yang disebutMessageHandler untuk memperluas aplikasi Layanan Web Anda. MessageHandler mirip dengan SOAPHandler, kecuali bahwa implementasi itu mendapat aksesMessageHandlerContext(ekstensi dari MessageContext). Melalui MessageHandlerContext, seseorang dapat mengakses Pesan dan memprosesnya menggunakan API Pesan. Saat saya memasukkan judul blog, pawang ini memungkinkan Anda mengerjakan Pesan, yang menyediakan cara-cara efisien untuk mengakses / memproses pesan bukan hanya pesan berbasis DOM. Model pemrograman dari penangan sama dan Penangan pesan dapat dicampur dengan penangan Logical dan SOAP standar. Saya telah menambahkan sampel di JAX-WS RI 2.1.3 yang menunjukkan penggunaan MessageHandler untuk mencatat pesan dan berikut adalah cuplikan dari sampel:

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

(kutipan akhir dari posting blog 2007)

Tidak perlu dikatakan Handler kustom Anda, LoggingHandlerdalam contoh, perlu ditambahkan ke Handler Chain Anda untuk memiliki efek apa pun. Ini sama dengan menambahkan yang lain Handler, sehingga Anda dapat melihat jawaban lain di halaman ini untuk mengetahui cara melakukannya.

Anda dapat menemukan contoh lengkap di repo Metro GitHub .

peterh
sumber
1

Anda dapat mencoba untuk meletakkan ServletFilterdi depan layanan web dan memeriksa permintaan dan tanggapan pergi / kembali dari layanan.

Meskipun Anda secara khusus tidak meminta proxy, terkadang saya menemukan tcptrace cukup untuk melihat apa yang terjadi pada koneksi. Ini alat yang sederhana, tanpa instal, itu menunjukkan aliran data dan dapat menulis ke file juga.

rsp
sumber
1

Dalam runtime Anda cukup menjalankan

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

sebagai dump adalah var publik yang didefinisikan di kelas sebagai berikut

public static boolean dump;
jozh
sumber
Bagi saya bekerja dengan com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true;
userfb
1

apakah saya benar dalam memahami bahwa Anda ingin mengubah / mengakses pesan XML mentah?

Jika demikian, Anda (atau karena ini berusia lima tahun, lelaki berikutnya) mungkin ingin melihat antarmuka Penyedia yang merupakan bagian dari JAXWS. Mitra klien dilakukan menggunakan kelas "Pengiriman". Bagaimanapun, Anda tidak perlu menambahkan penangan atau pencegat. Anda masih BISA, tentu saja. Kelemahannya begini, Anda benar-benar bertanggung jawab untuk membangun SOAPMessage, tetapi mudah, dan jika itu yang Anda inginkan (seperti yang saya lakukan) ini sempurna.

Berikut adalah contoh untuk sisi server (agak canggung, itu hanya untuk bereksperimen) -

@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;}


   }
}

Anda menerbitkannya seperti Anda akan 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);
}
}

Atau Anda bisa menggunakan kelas Endpoint untuk itu. Harapan yang telah membantu.

Dan oh, jika mau, Anda tidak perlu berurusan dengan tajuk dan barang, jika Anda mengubah mode layanan ke PAYLOAD (Anda hanya akan mendapatkan Soap Body).

Aneesh Barthakur
sumber
1

dengan file konfigurasi logback.xml, Anda dapat melakukan:

<logger name="com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe" level="trace" additivity="false">
    <appender-ref ref="STDOUT"/>
</logger>

Itu akan mencatat permintaan dan respons seperti ini (tergantung pada konfigurasi Anda untuk keluaran log):

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>--------------------
Christian Goudreau
sumber
1

Saya telah mencoba menemukan beberapa framework library untuk mencatat permintaan dan respons sabun layanan web selama beberapa hari. Kode di bawah ini memperbaiki masalah saya:

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");
JChanthamontry
sumber
0

Salah satu cara untuk melakukannya adalah tidak menggunakan kode Anda tetapi menggunakan sniffer paket jaringan seperti Etheral atau WireShark yang dapat menangkap paket HTTP dengan pesan XML sebagai payload, dan Anda dapat terus mencatatnya ke file atau lebih.

Tetapi pendekatan yang lebih canggih adalah menulis penangan pesan Anda sendiri. Anda dapat melihatnya di sini .

Shamik
sumber
0

Sebenarnya. Jika Anda melihat ke sumber HttpClientTransport Anda akan melihat bahwa itu juga menulis pesan ke java.util.logging.Logger. Yang berarti Anda juga dapat melihat pesan-pesan itu di log Anda.

Sebagai contoh jika Anda menggunakan Log4J2 yang perlu Anda lakukan adalah yang berikut:

  • tambahkan jembatan JUL-Log4J2 ke jalur kelas Anda
  • atur level TRACE untuk paket com.sun.xml.internal.ws.transport.http.client.
  • tambahkan -Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager properti sistem ke aplikasi Anda mulai baris perintah mulai

Setelah langkah-langkah ini, Anda mulai melihat pesan SOAP di log Anda.

kemuliaan1
sumber
0

Ada beberapa jawaban menggunakan SoapHandlers di utas ini. Anda harus tahu bahwa SoapHandlers memodifikasi pesan jika writeTo(out)dipanggil.

Memanggil writeTo(out)metode SOAPMessage secara otomatis saveChanges()juga memanggil metode. Akibatnya semua data biner MTOM / XOP yang dilampirkan dalam pesan hilang.

Saya tidak yakin mengapa ini terjadi, tetapi tampaknya fitur yang didokumentasikan.

Selain itu, metode ini menandai titik di mana data dari semua objek AttachmentPart konstituen ditarik ke dalam pesan.

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

Mikko Tuominen
sumber
0

Jika Anda menjalankan server aplikasi IBM Liberty, cukup tambahkan ibm-ws-bnd.xml ke direktori 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>
Mikko Tuominen
sumber