ジャージーフィルタやインターセプタ内部からのアクセスリソースメソッドの引数。またはリソースメソッドでAOPを使います

kaqqao:

私は、ユーザーのIDと各要求にSLF4J MDCを豊かにしようとしています。問題は、ID、カスタムによって時々体に、時にはパスパラメータとして、多くの方法で渡され、時には注入することができるということであるValueFactoryProviderという最初の解読こと。

私は何とかすべて注入し(つまり、アクセスすることができれば、すでに直列化復元)パラメータ値を、私は簡単にこれらすべてのケースを扱うことができます。

たとえば、

次のようなリソースのために

@GET
//@Encrypted params are injected by a custom ValueFactoryProvider
public Something getSomething(@Encrypted("userId") String userId) {
    return ...;
}

@POST
public Something getSomething(@RequestBody RequestWithUserId requestWithUserId) {
    return ...;
}

私は、フィルタなどを持つことができます:

public class MdcFilter implements ContainerRequestFilter, ContainerResponseFilter {

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        Method theMethod = resourceInfo.getResourceMethod();
        for (Parameter parameter : theMethod.getParameters()) {
            //Deal with the @Encrypted case
            if (parameter.isAnnotationPresent(Encrypted.class) && parameter.getAnnotation(Encrypted.class).value().equals("userId")) {
                MDC.put("userId", somehowGetTheValue());
            }
            //Deal with the @RequestBody case
            if (parameter.isAnnotationPresent(RequestBody.class) && parameter.getType().equals(RequestWithUserId.class)) {
                MDC.put("userId", ((RequestWithUserId)somehowGetTheValue()).getUserId());
            }
            ... //other possibilities
        }
    }

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        MDC.clear();
    }
}

しかし、私は実装する方法が表示されないsomehowGetTheValueから、どちらかのContainerRequestFilter迎撃や何かを...

ポールSamsotha:

ジャージーは使用していますHK2を依存性注入のためにボンネットの下に。そして、HK2はありAOPサポートをご利用の場合の1つのオプションは、このAOPサポートを使用するだろう。あなたがする必要があるすべては実装しているMethodInterceptorInterceptionServiceではMethodInterceptor、あなたはからすべての引数を取得することができMethodInvocation、あなたはからパラメータの注釈を取得することができますMethod

class MyMethodInteceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();
        Object[] args = invocation.getArguments();

        // do your logging or whatever with the args.

        // invoke method and get return value.
        Object returnValue = invocation.proceed();
        // if you want to do something with the return
        // value before returning it, you can.

        return returnValue;
    }
}

インターセプターを使用するには、設定しますInterceptionService

public class MyInterceptionService implements InterceptionService {

    private final static MethodInterceptor METHOD_INTERCEPTOR 
            = new MyMethodInterceptor();
    private final static List<MethodInterceptor> METHOD_LIST
            = Collections.singletonList(METHOD_INTERCEPTOR);

    @Override
    public Filter getDescriptorFilter() {
        return BuilderHelper.allFilter();
    }

    @Override
    public List<MethodInterceptor> getMethodInterceptors(Method method) {
        // you implement shouldIntercept
        if (shouldIntercept(method)) {
            return METHOD_LIST;
        }
        return null;
    }

    @Override
    public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> constructor) {
        return null;
    }
}

あなたには傍受されるべき方法を決定getMethodInterceptors()する方法。この方法は、傍受されなければならない場合は、そうでない場合はnullを返し、インターセプタのリストを返します。これを処理する一般的な方法は、カスタムアノテーションを作成し、ちょうど方法に注釈を付けることです。上記の方法では、単にチェック

if (method.isAnnotationPresent(YourAnno.class)) {
    return METHOD_LIST;
}

それはすべてを動作させるために、あなただけ登録する必要がありInteceptionServiceHK2と。あなたにはそれを行うことができAbstractBinder、あなたのDIを設定するには、ジャージーアプリで使用されているものです。

ResourceConfig config = new ResourceConfig();
config.register(new AbstractBinder() {
    @Override
    protected void configure() {
        bind(MyInterceptionService.class)
                .to(InterceptionService.class)
                .in(Singleton.class);
    }
});

あなたには、完全な例を参照することができ、このGitHubのレポHK2サイトでの公式の例もあります。ただ、ポストの上部にある「AOPサポート」のリンクを参照してください。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=189158&siteId=1