I'm really new to DI and am having tons of problems with basic things in JAX-RS.
I have a filter called SentryAuthFilter
which subclasses an abstract class called AuthFilter
. AuthFilter
implements ContainerRequestFilter
, ContainerResponseFilter
and WriterInterceptor
. Because AuthFilter
is abstract, the methods, like configure()
, matchResource()
, ... are implemented actually in SentryAuthFilter()
(and other classes that subclass AuthFilter
.
In SentryFilter
, I need access to the HTTPServletRequest
and HTTPServletResponse
in my filter
method.
@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;
}
...
}
The problem is that request
and response
is null. I've looked at 8 different questions regarding this topic and I can't find one that explains how HTTPServletRequest and HTTPServletResponse are injected. They just say that it is a singleton proxy object and you shouldn't need to explicitly inject it, just use @Context
. Clearly, @Context
is not working.
The class that actually calls SentryFilter
or any of the other classes that implement AuthFilter
is called DynamicAuthFilter
. This DynamicAuthFilter
is "registered" in a class that implements 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));
}
}
According to this, it seems like context registration is how @Context values are filled. So I'm not sure if the issue is that registration in AuthenticationDynamicFeature
is wrong, or if I'm missing something else. DynamicAuthFilter
does nothing else except call SentryFilter
, AnotherAuthFilter
, etc, so I don't use @Context
in it.
Sorry for the long post, but I'm really confused.