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.
authenticator
, tetapi di mana saya bisa mendapatkanrequest
atauresponse
? - person Jeremy Fisher   schedule 10.01.2018ServiceLocator
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.2018List<AuthFilter> filters...
itu penting karena mengumpulkan berbagai filter yang ditentukan untuk API tertentu berdasarkan anotasi.DynamicAuthFilter
diperlukan untuk memanggil filter tersebut. Jadi maksud Anda metodeconfigure
saya seharusnya hanya berupa barisList<AuthFilter> filters
, lalu membuat objek DynamicAuthFilter yang meneruskan filter, dan kemudian menggunakanServiceLocator
untuk menyuntikkanDynamicAuthFilter
? - person Jeremy Fisher   schedule 10.01.2018AuthenticationDynamicFeature
saya. Saya menambahkan ServiceLocator ke Konstruktor saya yang sudah memiliki @Inject dan menggunakanlocator.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.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