4

別のシステムから xml イベントを受信し、特定のワークフローを使用してそれらを処理し、潜在的なエラーのリストを HTTP 応答として返す Web サービスがあります。

イベント処理ワークフローは、 Guava の EventBusを使用して実装されたいくつかのハンドラー (たとえば、 PreprocessorPersister、およびValidator ) で構成されます。ハンドラは互いにイベントを送信します。このようなもの:

public class RequestHandler {

    @RequestMapping
    public Errors handleRequest(String xmlData) {
        eventBus.post(new XmlReceivedEvent(xmlData));
        ...
        return errors; // how to get errors object from the last handler in chain ? 
    }
}

public class Preprocessor {

    @Subscribe
    public void onXmlReceived(XmlReceivedEvent event) {
       // do some pre-processing
       ...  
       eventBus.post(new PreprocessingCompleteEvent(preprocessingResult)); 
    }
}

public class Persister {

    @Subscribe
    public void onPreprocessingComplete(PreprocessingCompleteEvent event) {
       // do some persistence stuff
       ...    
       eventBus.post(new PersistenceCompleteEvent(persistenceResult)); 
    }
}

public class Validator {

    @Subscribe
    public void onPersistenceComplete(PersistenceCompleteEvent event) {
       // do validation
       ...    
       eventBus.post(new ValidationCompleteEvent(errors)); // errors object created, should be returned back to the RequestHandler 
    }
}

問題は、処理結果をValidatorハンドラーから開始点 ( RequestHandler ) に深く戻して、ユーザーが HTTP 応答を受信できるようにする方法です。

次の 2 つのオプションを検討します。

  1. エラー オブジェクトを最初の XmlReceivedEvent に設定し、処理の完了後に取得します。

    public class RequestHandler {
    
        @RequestMapping
        public Errors handleRequest(String xmlData) {
            XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
            eventBus.post(event);
            ...
            return event.getErrors(); 
        }
    }
    

ただし、その場合、チェーン内の各イベントにエラー オブジェクトを渡して、Validatorが実際のデータを入力できるようにする必要があります。

  1. RequestHandlerValidatorからValidationCompleteEventにサブスクライブし、エラー オブジェクトを内部に入力します。

    public class RequestHandler {
    
        private Errors errors;
    
        @RequestMapping
        public Errors handleRequest(String xmlData) {
            XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
            eventBus.post(event);
            ...
            return this.errors; // ??? 
        }
    
        @Subscribe
        public void onValidationComplete(ValidationCompleteEvent event) {
            this.errors = event.getErrors();
        }
    }
    

ただ、残念ながらRequestHandlerは Spring のステートレス サービス (シングルトン) であるため、クラス フィールドにデータを保存することは避けたいと考えています。

どんなアイデアでも大歓迎です。

4

1 に答える 1

10

そのようなワークフローが必要な場合は、GuavaEventBusを使用しないでください。EventBus特に、イベントの投稿者が購読者を知らない、または気にしないでイベントを購読者に投稿できるようにすることを目的としています...そのため、購読者からイベントの投稿者に結果を返すことはできません。

プリプロセッサ、パーシスタ、バリデーターを挿入し、それらのメソッドを直接呼び出すなど、ここではもっと簡単なことを行う必要があるように思えます。

于 2012-04-25T13:46:35.143 に答える