5

ジャージーの射出機構がよくわかりません。JAX-RS 仕様 ( http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-520005 ) では、アプリケーション サブクラス、ルート リソース クラス、およびプロバイダーで @Context を介した注入が可能であると述べられています。

起動時にインスタンス化され、リクエストごとに呼び出されるメソッドを持つクラスができました。メソッド内で、現在の UriInfo オブジェクトにアクセスする必要があります。問題は、このメソッドが私のコードから呼び出されないことです。したがって、UriInfo をメソッドに直接渡すことはできません。

私は実際にこのようなことをしたい:

public class MyClass implements ThirdPartyInterface {

    // not possible because class is no Application subclass, root resource class or provider
    @Context
    private UriInfo uriInfo;

    public void methodCallebByThirdPartyCode() {
        Uri requestUri = uriInfo.getRequestUri();

        // do something
    }
}

これを試しました。明らかに成功していません:

public class MyClass implements ThirdPartyInterface {

    private UriInfo uriInfo;

    public MyClass(UriInfo uriInfo) {
        this.uriInfo = uriInfo;
    }

    public void methodCallebByThirdPartyCode() {
        Uri requestUri = uriInfo.getRequestUri();

        // do something
    }
}

@Provider
@Produces(MediaType.WILDCARD)
public class MyBodyWriter implements MessageBodyWriter<MyView> {

    @Context
    private UriInfo uriInfo;

    private MyClass myClass;

    private ThirdPartyClass thirdPartyClass;

    public MyBodyWriter() {
        // uriInfo is null at this time :(
        myClass = new MyClass(uriInfo);

        thirdPartyClass = new ThirdPartyClass();
        thirdPartyClass.register(myClass);
    }

    public void writeTo(final MyView view, final Class<?> type, /* and so on */) throws IOException, WebApplicationException {
        // execute() calls MyClass#methodCallebByThirdPartyCode()
        thirdPartyClass.execute();
    }
}

私が考えることができる唯一の回避策はこれです。あまりきれいではないと思います:

public class MyClass implements ThirdPartyInterface {

    private UriInfo uriInfo;

    public void setUriInfo(final UriInfo uriInfo) {
        this.uriInfo = uriInfo;
    }

    public void methodCallebByThirdPartyCode() {
        Uri requestUri = uriInfo.getRequestUri();

        // do something
    }
}

@Provider
@Produces(MediaType.WILDCARD)
public class MyBodyWriter implements MessageBodyWriter<MyView> {

    @Context
    private UriInfo uriInfo;

    private MyClass myClass;

    private ThirdPartyClass thirdPartyClass;

    public MyBodyWriter() {
        myClass = new MyClass();

        thirdPartyClass = new ThirdPartyClass();
        thirdPartyClass.register(myClass);
    }

    public void writeTo(final MyView view, final Class<?> type, /* and so on */) throws IOException, WebApplicationException {
        myClass.setUriInfo(uriInfo);

        // execute() calls MyClass#methodCallebByThirdPartyCode()
        thirdPartyClass.execute();

        myClass.setUriInfo(null);
    }
}

より良い解決策があることを願っていますが、完全に間違った方向に進んでいる可能性があります。

ありがとう!

4

1 に答える 1