web-dev-qa-db-ja.com

Jerseyのライフサイクル中にどのようにリクエストをインターセプトしますか?

ジャージーを1年の大部分で使用してきましたが、答えが見つからない問題に出くわしました。ジャージーのリクエストライフサイクルをどのようにインターセプト(またはフック)しますか?

理想的には、コンテナがネットワークからのリクエストを受け入れてからハンドラメソッドが呼び出されるまでの間に、カスタムフィルタリング/検証/拒否を実行できるようになります。サブパスでインターセプターをフィルタリングする簡単な方法がある場合のボーナスポイント(たとえば、/の下にあるものには1つのインターセプターがあり、/ user /の下にあるものには別のインターセプターがあるなど)。

ありがとう!

編集:少しわかりやすくするために、ここでの一般的な考え方は、各ハンドラーメソッドから明示的にそのコードを呼び出すことなく、多くのAPI呼び出しで実行されるコードを作成できるようにすることです。これにより、余分なコードが削減され、リクエストコンテキストを渡す必要がなくなります。

48
cww

答えを見つけました。

最初に、ContainerRequestFilterを実装するクラスを作成します。インターフェイスは、フィルタリングが行われる次のメソッドを指定します。 ContainerRequestオブジェクトには、現在のリクエストに関する情報が含まれています。

public ContainerRequest filter(ContainerRequest req);

その後、web.xmlのサーブレット構成に次のXMLを含めます

<init-param>
  <param-name>com.Sun.jersey.spi.container.ContainerRequestFilters</param-name>
  <param-value>path.to.filtering.class</param-value>
</init-param>

ソース:

http://jersey.576304.n2.nabble.com/ContainerRequestFilter-and-Resources-td4419975.htmlhttp://markmail.org/message/p7yxygz4wpakqno5

50
cww

このスレッドは少し古いですが、リクエストのbefore and afterの両方を傍受するのに十分な時間を過ごしていました。 Webでの長い検索の後、私はついにこれを見つけました。

<init-param>
    <param-name>com.Sun.jersey.spi.container.ContainerResponseFilters</param-name>
    <param-value>blah.LoggingFilter</param-value>
</init-param>
<init-param>
    <param-name>com.Sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>blah.LoggingFilter</param-value>
</init-param>

そして、このクラス:

public class LoggingFilter extends LoggingFilter implements ContainerRequestFilter {

    private static final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
    public static boolean verboseLogging = false;

    @Override
    public ContainerRequest filter(ContainerRequest arg0) {
        startTime.set(System.currentTimeMillis());
        return arg0;
    }

    @Override
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
        System.out.println(System.currentTimeMillis() - startTime.get().longValue());
        StringBuilder sb = new StringBuilder();
        sb.append("User:").append((request.getUserPrincipal() == null ? "unknown" : request.getUserPrincipal().getName()));
        sb.append(" - Path:").append(request.getRequestUri().getPath());
        //...
    }

これは、最初と最後でリクエストをインターセプトするので、タイマーなどを入れることができます。

これはJersey 1.17で機能します。 2.xについてはわかりません。

9
markthegrea

サーバー部分では、Jersey Specificクラスを使用して次のようなことを行います:ContainerResponseFilter

署名は次のとおりです。

public ContainerResponse filter(ContainerRequest request, ContainerResponse response)

次のような呼び出しを行うことができます:

Object entity  = response.getEntity();
    ... your logic here ...
return response;

これは助けになりますか?.

0
a1o1