エラーが発生した場合、未加工のSOAPポストリクエストをログに記録したいのですが、JAX-WSを使用しています。どんな助けでもありがたいです。
例外が応答で発生した場合にのみ、JAX-WSリファレンス実装(JDK 1.5以降に含まれるもの)で公開されたWebサービスの生の要求/応答XMLにアクセスする簡単な方法(別名:プロキシを使用しない)はありますか?生のログを記録したいSOAP reuestなので、後の段階で任意のWebサービスクライアントを使用してテストできます
使用する
com.Sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true
そして
com.Sun.xml.internal.ws.transport.http.HttpAdapter.dump=true
代わりに(パッケージ名の「内部」に注意)、これは私にとってはトリックでした。
乾杯、トルステン
私がこれに言及すると思っただけです:
internal
が含まれるプロパティ名をいつ使用し、いつ使用しないかという質問Metro Guide を読むと、次のように指示されます。
クライアント上:
com.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
サーバー上:
com.Sun.xml.ws.transport.http.HttpAdapter.dump=true
ただし、JDKにJAX-WS RIライブラリが標準で含まれている場合(Java 6の場合))、Sunはプロパティ名を「internal」に変更する必要があったようです。したがって、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
。
誰かがこれについて内面の知識を持っていて、これが真実かどうか言うことができれば嬉しいです。
トルステンの答えに加えて
com.Sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true
WebServiceClientオブジェクト(Serviceを拡張するオブジェクト)をインスタンス化する前に、必ずこれを設定してください
最初に試したいのは、次のシステムプロパティの一方または両方を使用することです。
クライアント:
com.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
サーバ:
com.Sun.xml.ws.transport.http.HttpAdapter.dump=true
Jboss 6.1を使用していて、SOAP WebサービスへのJAX-WS生成クラス要求のログを印刷する場合は、ファイル/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
システムプロパティを使用しても問題ありません(ここに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ボディのキャプチャの詳細は私の回答にあります SOAPハンドラーからWebサービスクライアントにデータを返すにはどうすればよいですか?
ここに重要な部分があります:
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 = bindingProvider.getBinding().getHandlerChain();
handlerChain.add(new MsgLogger());
bindingProvider.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);
この解決策(これはスケルトンであり、適切なエラー処理/エッジのケースはあなた次第です)を使用して、応答があったときにログに記録することにします。
これは私のために働きました:
-Dcom.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
必要なのはハンドラーだと思います。以下を参照してください。 http://jax-ws.Java.net/articles/handlers_introduction.html
ハンドラーを使用すると、Webサービス呼び出しをインターセプトして、すべてのSOAPメッセージにアクセスできます。