web-dev-qa-db-ja.com

Apache CXFを使用したXMLとしての要求/応答のログ記録

CXFを使用して、理想的にはアプリケーションが何をしているのかを監視できるように別のファイルにXMLとして要求/応答を記録することは可能ですか?

23
irishguy

エンドポイントとクライアントに次を追加します。

<jaxws:features>
    <bean class="org.Apache.cxf.feature.LoggingFeature" />
</jaxws:features>

これにより、すべてがサーバーログに記録されます。

他の場所でログを記録する場合は、組み込みのCXF LoggingInInterceptorおよびLoggingOutInterceptorのソースコードを確認します。あなたは彼らが出入りする途中でメッセージをつかみ、あなたが好きなことをするために彼らが使用するパターンに従うことができます。

次のようなものを使用して、独自のインターセプターをチェーンに追加します。

<jaxws:inInterceptors>
    <ref bean="myLoggingInInterceptor" />
</jaxws:inInterceptors>
17
BPS

それで、私はこれをもう少し試しました。 XMLリクエストとリプライをログに記録し、Log4Jを使用している場合、CXFのログレベルをlog4j.xmlファイルで設定する必要があります(> = INFO):

<logger name="org.Apache.cxf" >
    <level value="INFO" />
</logger>

そして、cxf.xmlファイルには次のものが含まれている必要があります。

<cxf:bus>
    <cxf:features>
        <cxf:logging/>
    </cxf:features>
</cxf:bus> 

両方のファイルがCLASSPATHにある必要があります。

Soapメッセージを表示するには、これをコードに追加します。

Client client = ClientProxy.getClient(service);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
28
Asturio

リクエストsoap xmlは、カスタムInインターセプターによって簡単に記録できます。たとえば、「wsLoggingInInterceptor」という名前のインターセプターがあるため、コンテキストファイルでは次のようになります。

<bean id="loggingInInterceptor" class="org.Apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutInterceptor" class="org.Apache.cxf.interceptor.LoggingOutInterceptor"/>
<bean id="wsLoggingInInterceptor" class="org.jinouts.webservice.logging.WSLoggingInInterceptor"/>


   <cxf:bus>
        <cxf:inInterceptors>
            <ref bean="loggingInInterceptor"/>
            <ref bean="wsLoggingInInterceptor"/>
        </cxf:inInterceptors>
        <cxf:outInterceptors>
            <ref bean="logOutInterceptor"/>            
       </cxf:outInterceptors>
    </cxf:bus>

クラスでは、次のようにリクエストXMLを取得できます。

public class WSLoggingInInterceptor extends AbstractSoapInterceptor
{

    public WSLoggingInInterceptor ()
    {
        super(Phase.RECEIVE);
    }

    @Override
    public void handleMessage ( SoapMessage message ) throws Fault
    {
        //get the remote address
        HttpServletRequest httpRequest = (HttpServletRequest) message.get ( AbstractHTTPDestination.HTTP_REQUEST );
        System.out.println ("Request From the address : " + httpRequest.getRemoteAddr ( ) );

        try
        {
            // now get the request xml
            InputStream is = message.getContent ( InputStream.class );
            CachedOutputStream os = new CachedOutputStream ( );
            IOUtils.copy ( is, os );
            os.flush ( );
            message.setContent (  InputStream.class, os.getInputStream ( ) );
            is.close ( );

            System.out.println ("The request is: " + IOUtils.toString ( os.getInputStream ( ) ));
            os.close ( );
        }

        catch ( Exception ex )
        {
            ex.printStackTrace ( );
        }

    }

}

ここで、リクエストの送信元のアドレスも記録しています。 「HttpServletRequest」オブジェクトからいくつかの詳細情報を取得することもできます。以下からより多くを得ることができます: http://cxf.Apache.org/docs/interceptors.html

応答XMLをログに記録するには、 このスレッド をご覧ください

20
Asraful Haque

Java構成でSpringを使用している場合、Apache CXFでSOAPメッセージのロギングをアクティブ化する簡単な方法が2つあります。

  1. SpringBusで直接-これは、すべてのCXFエンドポイントのメッセージを記録する場合に便利です。

    @Bean(name=Bus.DEFAULT_BUS_ID) public SpringBus springBus() { SpringBus springBus = new SpringBus(); LoggingFeature logFeature = new LoggingFeature(); logFeature.setPrettyLogging(true); logFeature.initialize(springBus); springBus.getFeatures().add(logFeature); return springBus; }

  2. 公開されたすべてのCXFエンドポイントで個別にロギングをアクティブ化します

    @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), weatherService()); endpoint.publish(SERVICE_NAME_URL_PATH); endpoint.setWsdlLocation("Weather1.0.wsdl"); LoggingFeature logFeature = new LoggingFeature(); logFeature.setPrettyLogging(true); logFeature.initialize(springBus()); endpoint.getFeatures().add(logFeature); return endpoint; }

LoggingFeature.setPrettyLogging(true);を思い出してください。きれいに印刷されたSOAPメッセージとLoggingFeature.initialize(springBus());を表示するメソッド。 -後者がなければ、魔法は起こりません。よりクリーンなコードの場合、LoggingFeatureを個別のBeanとして分離し、SpringBusまたはEndpoint-Beanのいずれかに挿入することもできます。

7
jonashackt

エンドポイントプロパティに独自のロガーを追加する方がはるかに簡単です。この場合、デフォルトのロギングインターセプターはエンドポイントのプロパティでロガーを探し、それが見つかった場合はそれを使用し、そうでない場合はデフォルトを作成します。これが私の使用例です:

<jaxws:endpoint
        xmlns:client="http://service.info.client.diasoft.services.stream.integration.cib.sberbank.ru"
        address="/diasoft/clientInfoWS"
        serviceName="client:ClientWS"
        implementor="#clientServiceImpl">
    <jaxws:properties>
        <entry key="MessageLogger" value-ref="logger"/>
    </jaxws:properties>
    <jaxws:features>
        <bean class="org.Apache.cxf.feature.LoggingFeature"/>
    </jaxws:features>
</jaxws:endpoint>


<bean id="logger" class="org.Apache.cxf.common.logging.LogUtils" factory-method="getLogger">
    <constructor-arg value="ru.sberbank.cib.integration.stream.services.diasoft.client.info.service.ClientWSImpl"/>
</bean>
2
Mike