Truy tìm yêu cầu / phản hồi XML bằng JAX-WS


172

Có một cách dễ dàng (còn gọi là: không sử dụng proxy) để có quyền truy cập vào XML yêu cầu / phản hồi thô cho dịch vụ web được xuất bản với triển khai tham chiếu JAX-WS (một trong JDK 1.5 trở lên)? Có thể làm điều đó thông qua mã là những gì tôi cần làm. Chỉ cần nó đăng nhập vào một tệp bằng các cấu hình ghi nhật ký thông minh sẽ là tốt nhưng đủ.

Tôi biết rằng các khung công tác phức tạp và hoàn chỉnh khác tồn tại có thể làm điều đó, nhưng tôi muốn giữ nó đơn giản nhất có thể và trục, cxf, v.v ... tất cả đều thêm chi phí đáng kể mà tôi muốn tránh.

Cảm ơn!


5
Chỉ cần lưu ý: JAX-WS là một tiêu chuẩn, mà CXF thực hiện.
Bozho

Đặt các thuộc tính và biến môi trường của hệ thống Java, xem: <br> stackoverflow.com/questions/7054972/
Kẻ

Câu trả lời:


282

Các tùy chọn sau cho phép ghi nhật ký tất cả thông tin liên lạc vào bảng điều khiển (về mặt kỹ thuật, bạn chỉ cần một trong số này, nhưng điều đó phụ thuộc vào các thư viện bạn sử dụng, do đó, đặt cả bốn là tùy chọn an toàn hơn). Bạn có thể đặt nó trong mã như trong ví dụ hoặc làm tham số dòng lệnh bằng cách sử dụng -D hoặc làm biến môi trường như Upendra đã viết.

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

Xem câu hỏi Truy tìm yêu cầu / phản hồi XML bằng JAX-WS khi xảy ra lỗi để biết chi tiết.


7
Cảm ơn, đây là câu trả lời tốt nhất mà tôi đã tìm thấy cho vấn đề này
M Smith

5
Điều này KHÔNG làm việc cho tôi, khi CLIENT chạy trong Tomcat. Chỉ các công cụ -D hoạt động. Tôi tin rằng điều này là do cấu trúc classLoader trong Tomcat?
Rop

3
System.setProperty ("com.sun.xml.iternal.ws.transport.http.client.HttpTransportPipe.dump", "true"); là onefor bên phải JAX-WS 2.2 RI được gói trong JDK7 và được sử dụng theo mặc định
Glenn Bech

1
đối với công việc này trong tomcat, bạn cần thêm các lệnh này vào JAVA_OPTS trong catalina.sh, ví dụ trên dòng đầu tiên thêm: JAVA_OPTS = "-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom. sun.xml.iternal.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom.sun.xml.ws.transport.http.HttpAd Module.dump = true -Dcom.sun.xml.i INTERNal.ws.transport. http.HttpAd Module.dump = true "sau đó bạn có thể kiểm tra catalina.out và đầu ra từ đây sẽ hiển thị ở đó.
lừa

4
Đồng thời thêm System.setProperty ("com.sun.xml.iternal.ws.transport.http.HttpAd Module.dumpTrưỡng", "999999"); để không có yêu cầu và đầu ra phản hồi bị cắt ngắn
8bitme

84

Đây là giải pháp trong mã thô (kết hợp với nhau nhờ stjohnroe và Shamik):

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

Trong đó SOAPLoggingHandler (được trích xuất từ ​​các ví dụ được liên kết):

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
Xem liên kết nếu bạn vẫn không thấy phản hồi / yêu cầu xml với mã ở trên: stackoverflow.com/questions/2808544/
Kẻ

2
Điều này phụ thuộc vào sự tồn tại của một đối tượng SOAPMessage, vì vậy nó sẽ thất bại (chỉ in một ngoại lệ, nhưng không phải là dấu vết) nếu bạn nhận được phản hồi không đúng từ máy chủ. Kiểm tra câu trả lời của tôi, nếu bạn cần một dấu vết ngay cả khi thign đi sai.
Ông Napik

Trong đoạn trích ở trên cùng: liên quan đến dòng cuối cùng ep.publish(publishURL);: là gì publishURL(Trong mã của tôi, url wsdl được bao gồm trong chính dịch vụ; tôi không có bất kỳ url nào bên ngoài. Tôi bỏ lỡ điều gì?)
badera

Nếu bạn muốn xuất bản nó trên tất cả các giao diện thì PublishUrl là một cái gì đó như thế này (hltp = http): "hltp: //0.0.0.0: 8080 / độc lập / dịch vụ". Trong trường hợp cụ thể này, bạn có thể truy cập dịch vụ tại "hltp: //127.0.0.1: 8080 / độc lập / dịch vụ / yourService" trong đó "yourService" là vị trí cổng wsdl được xác định trong wsdl.
risop

@ Mr.Napik: Nhưng theo cách này, bạn vẫn có thể cung cấp cơ sở ghi nhật ký của riêng mình, điều này thật tuyệt khi bạn sử dụng khung đăng nhập.
Daniel

54

Trước khi bắt đầu tomcat, hãy đặt JAVA_OPTSnhư bên dưới trong Linux envs. Sau đó bắt đầu Tomcat. Bạn sẽ thấy yêu cầu và phản hồi trong catalina.outtập tin.

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

3
Xuất sắc. Đây là câu trả lời tốt nhất IMHO.
Pablo Santa Cruz

Vì một số lý do, đối với tôi đó là:-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
tibo

Vì một số lý do, điều này chỉ hoạt động trên một trong 3 dịch vụ web của tôi (tôi có 3 dịch vụ web JAX-WS trong ứng dụng web Tomcat của mình). Bất cứ ý tưởng tại sao nó sẽ không hoạt động trên cả 3?
David Brossard

Tôi đã làm việc tốt để xem tại sao thử nghiệm của mình thất bại (Đặt tùy chọn trong 'cấu hình chạy' của thử nghiệm của tôi là 'đối số VM').
MrSmith42

Bạn Sire chỉ exploeded internet với câu trả lời tuyệt vời nhất
vikingsteve

16

Đặt các thuộc tính hệ thống sau, điều này sẽ cho phép ghi nhật ký xml. Bạn có thể đặt nó trong java hoặc tập tin cấu hình.

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

nhật ký giao diện điều khiển:

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

Tiêm SOAPHandlervào giao diện điểm cuối. chúng tôi có thể theo dõi yêu cầu và phản hồi SOAP

Triển khai SOAPHandler với 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);

Khai báo bằng cách thêm @HandlerChain(file = "handlers.xml")chú thích vào giao diện điểm cuối của bạn.

handlers

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

}

Tôi đang theo dõi chính xác điều này. Tôi đang in thông báo sau khi sửa đổi tiêu đề, tuy nhiên tôi không thấy những thay đổi đó. Dường như thông báo không thay đổi cho đến khi nó rời khỏi phương thức
handleMessage

Nếu tôi gọi để in tin nhắn hai lần, lần thứ hai có cập nhật. Rất kỳ quặc
Iofacture

11

Có nhiều cách khác nhau để thực hiện việc này theo chương trình, như được mô tả trong các câu trả lời khác, nhưng chúng là các cơ chế khá xâm lấn. Tuy nhiên, nếu bạn biết rằng bạn đang sử dụng JAX-WS RI (còn gọi là "Metro"), thì bạn có thể thực hiện việc này ở cấp cấu hình. Xem ở đây để được hướng dẫn về cách làm điều này. Không cần phải lộn xộn với ứng dụng của bạn.


2
Metro = JAX-WS RI + WSIT (tức là JAX-WS RI! = Metro)
Pascal Thivent

@Pau: Đã sửa. Bạn biết đấy, thay vì bỏ phiếu cho tôi vì điều đó, bạn có thể nỗ lực một chút và đề xuất một liên kết thay thế.
skaffman

1
Nếu tôi đã tìm thấy một, chắc chắn tôi sẽ đặt nó. Đừng coi đó là chuyện cá nhân. bỏ phiếu bầu;)
Pau

Liên kết bị hỏng một lần nữa (có chuyện gì với java.net ???). Tôi nghĩ rằng đây là liên kết mới: metro.java.net/nonav/1.2/guide/Logging.html
sdoca

9

// Giải pháp này cung cấp một cách lập trình thêm trình xử lý cho dịch vụ web clien với cấu hình XML

// Xem tài liệu đầy đủ tại đây: http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htmlm#i222476

// Tạo lớp mới thực hiện 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) {
}
}

// Lập trình thêm LogMessageHandler của bạn

   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

Tôi đang đăng một câu trả lời mới, vì tôi không đủ danh tiếng để bình luận về câu trả lời do Antonio cung cấp (xem: https://stackoverflow.com/a/1957777 ).

Trong trường hợp bạn muốn thông báo SOAP được in trong một tệp (ví dụ: thông qua Log4j), bạn có thể sử dụng:

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

Xin lưu ý rằng trong một số trường hợp nhất định, phương thức gọi writeTo () có thể không hoạt động như mong đợi (xem: https://community.oracle.com/thread/1123104?tstart=0 hoặc https://www.java.net/node / 691073 ), do đó đoạn mã sau sẽ thực hiện thủ thuật:

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

Bạn cần triển khai javax.xml.ws.handler.LogicalHandler, trình xử lý này sau đó cần được tham chiếu trong tệp cấu hình trình xử lý, lần lượt được tham chiếu bởi chú thích @HandlerChain trong điểm cuối dịch vụ (giao diện hoặc cách triển khai) của bạn. Sau đó, bạn có thể xuất thông báo qua system.out hoặc logger trong quá trình triển khai processMessage của bạn.

Xem

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

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


2

Các câu trả lời được liệt kê ở đây hướng dẫn bạn sử dụng SOAPHandlerlà hoàn toàn chính xác. Lợi ích của cách tiếp cận đó là nó sẽ hoạt động với bất kỳ triển khai JAX-WS nào, vì SOAPHandler là một phần của đặc tả JAX-WS. Tuy nhiên, vấn đề với SOAPHandler là nó cố gắng thể hiện toàn bộ thông điệp XML trong bộ nhớ. Điều này có thể dẫn đến việc sử dụng bộ nhớ lớn. Các triển khai khác nhau của JAX-WS đã thêm cách giải quyết của riêng họ cho việc này. Nếu bạn làm việc với các yêu cầu lớn hoặc phản hồi lớn, thì bạn cần xem xét một trong những cách tiếp cận độc quyền.

Vì bạn hỏi về "cái được bao gồm trong JDK 1.5 trở lên", tôi sẽ trả lời liên quan đến cái được gọi là JAX-WS RI (hay còn gọi là Metro) chính thức, cái được bao gồm trong JDK.

JAX-WS RI có một giải pháp cụ thể cho việc này rất hiệu quả về mặt sử dụng bộ nhớ.

Xem https://javaee.github.io/metro/doc/user-guide/ch02.html#ffic-handlers-in-jax-ws-ri . Thật không may, liên kết đó hiện đã bị hỏng nhưng bạn có thể tìm thấy nó trên WayBack Machine. Tôi sẽ đưa ra những điểm nổi bật dưới đây:

Người dân Metro trở lại vào năm 2007 đã giới thiệu một loại xử lý bổ sung MessageHandler<MessageHandlerContext>, thuộc sở hữu của Metro. Nó hiệu quả hơn nhiều so SOAPHandler<SOAPMessageContext>với việc nó không cố gắng thực hiện biểu diễn DOM trong bộ nhớ.

Đây là văn bản quan trọng từ bài viết blog gốc:

MessageHandler:

Sử dụng khung Trình xử lý mở rộng được cung cấp bởi Đặc tả JAX-WS và tính trừu tượng hóa Thông báo tốt hơn trong RI, chúng tôi đã giới thiệu một trình xử lý mới được gọi MessageHandlerđể mở rộng các ứng dụng Dịch vụ web của bạn. MessageHandler tương tự như SOAPHandler, ngoại trừ việc triển khai nó được truy cập vàoMessageHandlerContext(một phần mở rộng của MessageContext). Thông qua MessageHandlerContext, người ta có thể truy cập Tin nhắn và xử lý nó bằng API Tin nhắn. Khi tôi đặt tiêu đề của blog, trình xử lý này cho phép bạn làm việc trên Tin nhắn, cung cấp các cách hiệu quả để truy cập / xử lý thư không chỉ là tin nhắn dựa trên DOM. Mô hình lập trình của các trình xử lý là giống nhau và các trình xử lý Message có thể được trộn lẫn với các trình xử lý Logical và SOAP tiêu chuẩn. Tôi đã thêm một mẫu trong JAX-WS RI 2.1.3 cho thấy việc sử dụng MessageHandler để ghi nhật ký tin nhắn và đây là đoạn trích từ mẫu:

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

(trích dẫn từ bài viết trên blog năm 2007)

Không cần phải nói Handler tùy chỉnh của bạn, LoggingHandlertrong ví dụ, cần phải được thêm vào Chuỗi Handler của bạn để có bất kỳ ảnh hưởng nào. Điều này giống như thêm bất kỳ câu hỏi nào khác Handler, vì vậy bạn có thể xem các câu trả lời khác trên trang này để biết cách thực hiện.

Bạn có thể tìm thấy một ví dụ đầy đủ trong repo Metro GitHub .


1

Bạn có thể thử đặt ServletFiltertrước dịch vụ web và kiểm tra yêu cầu và phản hồi sẽ đến / trả lại từ dịch vụ.

Mặc dù bạn đặc biệt không yêu cầu proxy, đôi khi tôi thấy tcptrace là đủ để xem những gì diễn ra trên một kết nối. Đây là một công cụ đơn giản, không cần cài đặt, nó cũng hiển thị các luồng dữ liệu và cũng có thể ghi vào tệp.


1

Trong thời gian chạy, bạn có thể thực hiện đơn giản

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

as dump là một var công khai được định nghĩa trong lớp như sau

public static boolean dump;

Đối với tôi làm việc với com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true;
userfb

1

Tôi có đúng không khi hiểu rằng bạn muốn thay đổi / truy cập thông điệp XML thô?

Nếu vậy, bạn (hoặc vì đây là năm tuổi, anh chàng tiếp theo) có thể muốn xem giao diện Nhà cung cấp là một phần của JAXWS. Đối tác khách hàng được thực hiện bằng cách sử dụng lớp "Công văn". Dù sao, bạn không phải thêm trình xử lý hoặc đánh chặn. Bạn vẫn CÓ THỂ, tất nhiên. Nhược điểm là theo cách này, bạn HOÀN TOÀN chịu trách nhiệm xây dựng SOAPMessage, nhưng nó dễ dàng, và nếu đó là những gì bạn muốn (như tôi đã làm) thì điều này là hoàn hảo.

Dưới đây là một ví dụ cho phía máy chủ (bit vụng về, nó chỉ để thử nghiệm) -

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


   }
}

Bạn xuất bản nó như bạn sẽ là một 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);
}
}

Hoặc bạn có thể sử dụng một lớp Endpoint cho nó. Hy vọng rằng đã được hữu ích.

Và ồ, nếu bạn muốn bạn không cần phải đối phó với các tiêu đề và nội dung, nếu bạn thay đổi chế độ dịch vụ thành PAYLOAD (Bạn sẽ chỉ nhận được Body Soap).


1

với các tệp cấu hình logback.xml, bạn có thể làm:

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

Điều đó sẽ ghi lại yêu cầu và phản hồi như thế này (tùy thuộc vào cấu hình của bạn cho đầu ra nhật ký):

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

Tôi đã cố gắng tìm một số thư viện khung để ghi lại yêu cầu và phản hồi xà phòng dịch vụ web trong một vài ngày. Mã dưới đây đã khắc phục sự cố cho tôi:

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

Một cách để làm là không sử dụng mã của bạn mà sử dụng các trình thám thính gói mạng như Etheral hoặc WireShark có thể chụp gói HTTP với thông điệp XML dưới dạng tải trọng cho nó và bạn có thể tiếp tục đăng nhập chúng vào một tệp.

Nhưng cách tiếp cận tinh vi hơn là viết trình xử lý tin nhắn của riêng bạn. Bạn có thể có một cái nhìn tại đây .


0

Thực ra. Nếu bạn nhìn vào các nguồn của httpClientTransport, bạn sẽ nhận thấy rằng nó cũng đang viết tin nhắn vào java.util.logging.Logger. Điều đó có nghĩa là bạn cũng có thể thấy những tin nhắn trong nhật ký của mình.

Ví dụ: nếu bạn đang sử dụng Log4J2, tất cả những gì bạn cần làm là như sau:

  • thêm cầu JUL-Log4J2 vào đường dẫn lớp của bạn
  • đặt mức TRACE cho gói com.sun.xml.i INTERNal.ws.transport.http.client.
  • thêm thuộc tính hệ thống -Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager vào dòng lệnh bắt đầu ứng dụng của bạn

Sau các bước này, bạn bắt đầu thấy các thông báo SOAP trong nhật ký của mình.


0

Có một vài câu trả lời bằng cách sử dụng SoapHandlers trong chủ đề này. Bạn nên biết rằng SoapHandlers sửa đổi thông báo nếu writeTo(out)được gọi.

Gọi writeTo(out)phương thức của SOAPMessage cũng tự động gọi saveChanges()phương thức. Kết quả là tất cả dữ liệu nhị phân MTOM / XOP được đính kèm trong một tin nhắn sẽ bị mất.

Tôi không chắc tại sao điều này xảy ra, nhưng nó dường như là một tính năng được ghi lại.

Ngoài ra, phương thức này đánh dấu điểm tại đó dữ liệu từ tất cả các đối tượng Đính kèm thành phần được kéo vào thông báo.

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


0

Nếu bạn tình cờ chạy một máy chủ ứng dụng IBM Liberty, chỉ cần thêm ibm-ws-bnd.xml vào thư mục 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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.