1

I've created a ContainerRequestFilter implementation. I'm facing up with some misunderstanding I don't quite solve.

This is my implementation:

@Provider
@PreMatching
@Secured
public class BearerFilter implements ContainerRequestFilter
{
    @Context private HttpServletRequest request;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException
    {
        //this.request is null here
    }
}

In order to register it on my jaxrs application:

@ApplicationPath(value = "cmng")
public class RestApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new HashSet<Class<?>>();
        resources.add(AccountEndpoint.class);
        //...
        return resources;
    }

    @Override
    public Set<Object> getSingletons() {
        Set<Object> singletons = new HashSet<Object>();
        singletons.add(new BearerFilter());  <<<<< manually created object.
        return singletons;
    }
}

So, BearerFilter object is created manually, by code. The problem appears here since dependency injection only works on instances created and managed by the container itself.

So I'm not able to inject objects inside a ContainerRequestFilter since it's not a created or managed object by container itself.

How could I solve that?

I'm using jaxrs.

Jordi
  • 20,868
  • 39
  • 149
  • 333

1 Answers1

1

The @Context annotation is from JAX-RS and it's not related to CDI in any way. The available types that can be injected with @Context can be seen in this answer.


According to the getSingletons() method documentation, the injection should work:

Get a set of root resource, provider and feature instances. Fields and properties of returned instances are injected with their declared dependencies (see Context) by the runtime prior to use.


But you always can use the getClasses() method to register your filter:

@Override
public Set<Class<?>> getClasses() {
    Set<Class<?>> classes = new HashSet<Class<?>>();
    classes.add(AccountEndpoint.class);
    classes.add(BearerFilter.class)
    return classes;
}

From the documentation:

Get a set of root resource, provider and feature classes. The default life-cycle for resource class instances is per-request. The default life-cycle for providers (registered directly or via a feature) is singleton.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • What about if I need to inject a custom created class object? This custom class is annotated with `@ApplicationScoped`. – Jordi Aug 18 '17 at 10:16
  • @Jordi Then you want to use the CDI `@Inject` annotation. Depending on the CDI version and on the bean discovery mode, you may need to use a scope annotation in your filter, such as `@Dependent`. – cassiomolin Aug 18 '17 at 10:19
  • I've used `@Inject protected MemcachedApplicationResources memcachedResources;` However it's `null`. Any ideas? – Jordi Aug 18 '17 at 10:20
  • @Jordi Check my previous comment. I think CDI is not managing your filter. Try to annotate it with `@Dependent`. – cassiomolin Aug 18 '17 at 10:23
  • @Jordi I assume, of course, your JAX-RS implementation works with CDI... – cassiomolin Aug 18 '17 at 10:30
  • Mmm... I think it so. Is it possible to run a jee7 stack application without CDI? – Jordi Aug 18 '17 at 10:35
  • @Yes, CDI is recommended but not mandatory. And, by the way, there's not such thing as _jee7_. It's _Java EE 7_. See more details in this [answer](https://stackoverflow.com/a/36703404/1426227). – cassiomolin Aug 18 '17 at 10:37
  • I've created a [new post](https://stackoverflow.com/questions/45755377/jax-rs-custom-class-object-no-injected-into-a-containerrequestfilter) here in order to face it up. Can you help me on there? – Jordi Aug 18 '17 at 11:19