HTTPServletRequest dan HTTPServletResponse tidak diisi dengan @Context

Saya benar-benar baru mengenal DI dan mengalami banyak masalah dengan hal-hal dasar di JAX-RS.

Saya memiliki filter bernama SentryAuthFilter yang mensubkelaskan kelas abstrak bernama AuthFilter. AuthFilter mengimplementasikan ContainerRequestFilter, ContainerResponseFilter dan WriterInterceptor. Karena AuthFilter bersifat abstrak, metode seperti configure(), matchResource(), ... sebenarnya diimplementasikan di SentryAuthFilter() (dan kelas lain yang mensubkelas AuthFilter.

Di SentryFilter, saya memerlukan akses ke HTTPServletRequest dan HTTPServletResponse dalam metode filter saya.

@Priority(Priorities.AUTHENTICATION)
public class SentryAuthFilter extends AuthFilter {

    @Context
    private HttpServletRequest request;

    @Context
    private HttpServletResponse response;

    ...



@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    SentryHttpServletResponseWrapper responseWrapper = new SentryHttpServletResponseWrapper(response);
    try {
        tomcatSSOFilter.doFilter(request, responseWrapper, (request1, response1) -> {});
    } catch (Exception e) {
        LOGGER.error("Error occurred executing TomcatSSOFilter", e);
        requestContext.abortWith(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build());
        return;
    }

    ...
 }

Masalahnya adalah request dan response adalah nol. Saya telah melihat 8 pertanyaan berbeda mengenai topik ini dan saya tidak dapat menemukan satu pun yang menjelaskan bagaimana HTTPServletRequest dan HTTPServletResponse disuntikkan. Mereka hanya mengatakan bahwa itu adalah objek proxy tunggal dan Anda tidak perlu memasukkannya secara eksplisit, cukup gunakan @Context. Jelas, @Context tidak berfungsi.

Kelas yang sebenarnya memanggil SentryFilter atau kelas lain mana pun yang mengimplementasikan AuthFilter disebut DynamicAuthFilter. DynamicAuthFilter ini "terdaftar" di kelas yang mengimplementasikan DynamicFeature

@Provider
public class AuthenticationDynamicFeature implements DynamicFeature {

    private final List<javax.inject.Provider<? extends AuthFilter>> filterProviders;

    /**
     * @param permissionAuthFilter permissionAuthFilter
     * @param aaaAuthFilter aaaAuthFilter
     * @param sentryAuthFilter sentryAuthFilter
     */
    @Inject
    public AuthenticationDynamicFeature(final javax.inject.Provider<SomeAuthFilter> someAuthFilter,
                                        final javax.inject.Provider<AnotherAuthFilter> anotherAuthFilter,
                                        final javax.inject.Provider<SentryAuthFilter> sentryAuthFilter) {
        this.filterProviders = ImmutableList.of(someAuthFilter, anotherAuthFilter, sentryAuthFilter);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {

            List<AuthFilter> filters = filterProviders.stream()
                    .map(javax.inject.Provider::get)
                    .filter(f -> f.matchResource(resourceInfo))
                    .peek(AuthFilter::configure)
                    .collect(Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf));

        context.register(new DynamicAuthFilter(filters));
    }
}

Menurut ini, sepertinya pendaftaran konteks adalah caranya @ Nilai konteks diisi. Jadi saya tidak yakin apakah masalahnya adalah pendaftaran di AuthenticationDynamicFeature salah, atau ada hal lain yang saya lewatkan. DynamicAuthFilter tidak melakukan apa pun kecuali memanggil SentryFilter, AnotherAuthFilter, dll, jadi saya tidak menggunakan @Context di dalamnya.

Maaf untuk postingannya yang panjang, tapi saya benar-benar bingung.


person Jeremy Fisher    schedule 09.01.2018    source sumber
comment
Mungkin cukup menyuntikkannya secara manual   -  person Paul Samsotha    schedule 10.01.2018
comment
Saya melihat postingan itu. Bagaimana cara mendapatkan akses ke objek HTTPServletRequest dan Response? Dalam postingan itu orang tersebut secara eksplisit memasukkan authenticator, tetapi di mana saya bisa mendapatkan request atau response?   -  person Jeremy Fisher    schedule 10.01.2018
comment
Anda menyuntikkan filter. Anda memiliki filternya. pencari lokasi.inject(filter)   -  person Paul Samsotha    schedule 10.01.2018
comment
Jadi gunakan ServiceLocator untuk menyuntikkannya, lalu daftarkan? Bagaimana cara mengisi nilai permintaan dan respons? Filter itu sendiri memerlukan nilai-nilai tersebut, jadi bagaimana memasukkan filter akan membuat @Context menyuntikkan HTTPServletRequest dan HTTPServletResponse?   -  person Jeremy Fisher    schedule 10.01.2018
comment
Anda tidak perlu mendaftarkannya. Suntikkan saja. Pencari lokasi akan memasukkan proxy. Baca sisa postingannya   -  person Paul Samsotha    schedule 10.01.2018
comment
Saya memang membacanya, tapi saya hanya bingung mau suntik apa secara spesifik. Keseluruhan baris List<AuthFilter> filters... itu penting karena mengumpulkan berbagai filter yang ditentukan untuk API tertentu berdasarkan anotasi. DynamicAuthFilter diperlukan untuk memanggil filter tersebut. Jadi maksud Anda metode configure saya seharusnya hanya berupa baris List<AuthFilter> filters, lalu membuat objek DynamicAuthFilter yang meneruskan filter, dan kemudian menggunakan ServiceLocator untuk menyuntikkan DynamicAuthFilter?   -  person Jeremy Fisher    schedule 10.01.2018
comment
Gunakan pencari lokasi untuk menyuntikkan objek apa pun yang ingin Anda suntik. Apakah DynamicAuthFilter yang ingin Anda masukkan? Tidak. Anda sudah meneruskan semua filter ke sana. Yang ingin Anda masukkan adalah filter yang tidak mendapatkan permintaan dan respons, SentryAuthFilter   -  person Paul Samsotha    schedule 10.01.2018
comment
Baiklah, apakah ada cara selain ServiceLocator untuk menyuntikkan SentryFilter? Rupanya mendapatkan ServiceLocator di jersey bukanlah hal yang sepele.   -  person Jeremy Fisher    schedule 10.01.2018
comment
Anda seharusnya bisa memasukkannya ke dalam fitur Anda. Ini adalah layanan seperti layanan lainnya.   -  person Paul Samsotha    schedule 10.01.2018
comment
Apakah Anda punya contohnya? Ketika saya mencobanya saya mendapatkan kesalahan?   -  person Jeremy Fisher    schedule 10.01.2018
comment
gist.github.com/psamsotha/6ac7816b4bf17eaebb87a876e7c730c7   -  person Paul Samsotha    schedule 10.01.2018
comment
Saya rasa saya perlu mengikat ServiceLocator, jika tidak saya mendapatkan Tidak ada kesalahan implementasi, yang kembali ke poin pertama saya tentang cara mendapatkan atau membuat ServiceLocator   -  person Jeremy Fisher    schedule 10.01.2018
comment
Versi Jersey apa yang Anda gunakan?   -  person Paul Samsotha    schedule 10.01.2018
comment
Jersey 2.19 sepertinya   -  person Jeremy Fisher    schedule 10.01.2018
comment
Seharusnya berhasil. Apakah Anda menjalankan pengujian saya?   -  person Paul Samsotha    schedule 10.01.2018
comment
Saya menerapkan perubahan Anda di AuthenticationDynamicFeature saya. Saya menambahkan ServiceLocator ke Konstruktor saya yang sudah memiliki @Inject dan menggunakan locator.inject(sentryAuthFilter) there. There's not really another place where I can inject it. I can't inject it in configure because I can't easily make a SentryAuthFilter` (ada argumen yang diteruskan ke konstruktornya) yang menurut saya tidak boleh saya pakai di AuthenticationDynamicFeature.   -  person Jeremy Fisher    schedule 10.01.2018
comment
Bagaimana Anda bisa melakukan itu jika itu adalah Penyedia dan bukan filter sebenarnya? Lakukan saja dalam metode peta di aliran Anda   -  person Paul Samsotha    schedule 10.01.2018
comment
jadi daripada .map(javax.inject.Provider::get) lakukan .map(this.locator.inject(javax.inject.Provider))? Itu gagal karena Object bukan antarmuka yang fungsional   -  person Jeremy Fisher    schedule 10.01.2018
comment
1) mendapatkan filter dari penyedia, 2) menyuntikkan filter, 3) mengembalikan filter.   -  person Paul Samsotha    schedule 10.01.2018