4

インストールされているアプリケーションによって送信された各 HTTP 応答のサイズを記録する Grails プラグインを作成しようとしています。これまでに試したアプローチは次のとおりです。

(1) をラップするサーブレット フィルタを記述しますresponse。応答ラッパーは、応答のバイト数をカウントする でOutputStream装飾します。OutputStreamこれらのクラスをここに示します

(2)プラグイン記述子にサーブレットフィルターを登録する

def doWithWebDescriptor = { webXml ->

    def contextParam = webXml.'context-param'

    contextParam[contextParam.size() - 1] + {
        'filter' {
            'filter-name'('countingFilter')
            'filter-class'(CountingFilter.name)
        }
    }

    def filter = webXml.'filter'
    filter[filter.size() - 1] + {
        'filter-mapping' {
            'filter-name'('countingFilter')
            'url-pattern'('/*')
        }
    }
}

(3) Grails フィルターで、次のように記述されたバイト数を取得してみてください。

afterView = {
    // countingFilter registers the response wrapper as an attribute of the request
    // named 'counter'
    request.getAttribute('counter').byteCount
}

ただし、値 0 は常に返されます。afterただし、上記のコードを Grails フィルターのとafterViewクロージャーの両方に追加すると、

after = {
    // returns 0
    request.getAttribute('counter').byteCount
}

afterView = {
    // returns the correct response size
    request.getAttribute('counter').byteCount
}

正しい応答サイズが返されるようになりましたが、サイトメッシュ レイアウトによって生成されたコンテンツが消え、GSP 自体にコンテンツだけが残っているようです。

それで、私は解決に近づいているようです。私の推測では、間違ったタイミングでバッファをフラッシュしているか、フィルタ チェーンの正しいポイントでフィルタが実行されていません。

これは、私が予想していたよりもはるかに困難であることが証明されています。もっと簡単な方法はありますか?

4

1 に答える 1

4

Grails にはこの機能が組み込まれています。ドキュメント化されていません。「-DGSPResponseWriter.enableContentLength=true」オプションを JVM 引数に追加して、システム プロパティ「GSPResponseWriter.enableContentLength」を true に設定します。詳細については、GSPResponseWriter のソース コードを参照してください。

これがデフォルトで有効になっていない理由は、一部の文字が UTF-8 エンコーディングでマルチバイトであるため、コンテンツの長さの計算が単純ではないためです。BoundedCharsAsEncodedBytesCounterは、計算を行うクラスです。

于 2013-03-21T14:58:05.317 に答える