6

JAX-WS WebService 呼び出しで完全な http 要求と応答をログに記録する必要があります。リクエストにはリクエストヘッダーとボディが必要で、レスポンスにはレスポンスヘッダーとボディが必要です。

いくつかの調査の後、プロパティでこの情報を取得できることがわかりました。

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

必要な情報を表示しますが、それはコンソールにダンプされ、内部リクエスト ID を使用してデータベースに保存する必要があります。

私はハンドラを実装しようとしました:

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outbound) {
            System.out.println("SOAP outbound!!!!!");
            Map<String, List<String>> responseHeaders = (Map<String, List<String>>) context
                    .get(SOAPMessageContext.HTTP_RESPONSE_HEADERS);
            try {
                String headers = getHeaders(responseHeaders);
                System.out.println(headers);
                String body = getBody(context.getMessage());
                System.out.println(body);
            } catch (Exception ex) {
                // TODO: What do I have to do in this case?
            }
        } else {
            System.out.println("SOAP inbound!!!!!");
            Map<String, List<String>> requestHeaders = (Map<String, List<String>>) context
                    .get(SOAPMessageContext.HTTP_REQUEST_HEADERS);
            try {
                String headers = getHeaders(requestHeaders);
                System.out.println(headers);
                String body = getBody(context.getMessage());
                System.out.println(body);
            } catch (Exception ex) {
                // TODO: What do I have to do in this case?
            }
        }
        return true;
    }

    private String getBody(SOAPMessage message) throws SOAPException, IOException {
        OutputStream stream = new ByteArrayOutputStream();
        message.writeTo(stream);
        return stream.toString();
    }

    public String getFullHttpRequest(HttpServletRequest request) throws IOException {
        InputStream in = request.getInputStream();
        String encoding = request.getCharacterEncoding();
        encoding = encoding == null ? "UTF-8" : encoding;
        String body = IOUtils.toString(in, encoding);
        return body;
    }

    private String getHeaders(Map<String, List<String>> headers) throws IOException {
        StringBuffer result = new StringBuffer();
        if (headers != null) {
            for (Entry<String, List<String>> header : headers.entrySet()) {
                if (header.getValue().isEmpty()) {
                    // I don't think this is legal, but let's just dump it,
                    // as the point of the dump is to uncover problems.
                    result.append(header.getValue());
                } else {
                    for (String value : header.getValue()) {
                        result.append(header.getKey() + ": " + value);
                    }
                }
                result.append("\n");
            }
        }
        return result.toString();
    }

}

ただし、この場合、http 要求ヘッダーと本文を取得できますが、応答では本文のみを取得し、http 応答ヘッダーは常に空です。

これをアーカイブする方法について何か考えはありますか? 目的は、完全な http 要求と応答をデータベースに格納できるようにすることです。

ありがとう!!

4

1 に答える 1

3

あなたも試すことができます

    -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true

ある種の Java EE アプリケーション サーバー内から (スタンドアロン クライアントからではなく) Web サービスを提供していると仮定しています。Web/Java EE コンテナーのコンテキストのような Java EE インフラストラクチャーHttpServletRequestやそのコンテキスト外にアクセスすることはできません。HttpServletResponse

実際のサーブレット応答オブジェクトを (Web コンテキスト内で) 手に入れようとすることができます。

    HttpServletResponse response = (HttpServletResponse) messageContext.get(SOAPMessageContext.SERVLET_RESPONSE); //messageContext is the SOAPMessageContext
    List<String> responseHeaderNames = (List<String>)response.getHeaderNames();
        for(String headerName : responseHeaderNames){
             //Do whatever you want with it.
              }

ただし、ハンドラー内の完全な応答ヘッダーを手に入れることができるとは思えません。あなたの質問にとても興味をそそられ、その部分の調査にかなりの時間を費やしました。私が見たすべてのコード サンプルでは、​​メトロ サイトの例でさえ、この機能を実装しようとはしていません。その理由は単純だと思います。ハンドラーが呼び出される時点で、コンテナーには、送信メッセージに http ヘッダーをスタンプするための十分な決定的な情報がない場合があります。何かを追加できるかもしれませんが、それも疑わしいです。

于 2012-11-09T05:28:50.423 に答える