11

I am trying to intercept a request to my JAX-RS webservice by a ContainerRequestFilter. I want to use it with a custom annotation, so I can decorate certain methods of the webservice. This should enable me to handle requests to this methods based on the information whether they are made on a secure channel or not, before the actual method is executed.

I tried different approaches, searched several posts and then implemented mostly based on the answer by Alden in this post. But I can't get it working.

I have a method test in my webservice decorated with my custom annotation Ssl.

@POST
@Path("/test")
@Ssl
public static Response test(){      
    System.out.println("TEST ...");
}

The annotation looks like this:

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface Ssl {}

Then I setup a filter implementation

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;

@Ssl
@Provider
public class SslInterceptor implements ContainerRequestFilter
{
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException
    {       
        System.out.println("Filter executed.");
    }
}

But the filter is never executed nor there occur any error messages or warnings. The test method runs fine anyway.

To resolve it, I tried to register the filter in the web.xml as described here.

<servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>

    <init-param>
      <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
      <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
    </init-param>

    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.my.packagewithfilter</param-value>
    </init-param>

    <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
        <param-value>com.my.packagewithfilter.SslInterceptor</param-value>
    </init-param>

    <init-param>  
      <param-name>jersey.config.server.provider.packages</param-name>  
      <param-value>com.my.packagewithfilter</param-value>
    </init-param>    

  </servlet>

But that also doesn't work. What am I missing? Any ideas how to make that filter work? Any help is really appreciated!

Community
  • 1
  • 1
ulrich
  • 1,431
  • 3
  • 17
  • 46

3 Answers3

10

You're using JAX-RS 2.0 APIs (request filters, name binding, ...) in your classes but Jersey 1 proprietary init params in your web.xml (package starting with com.sun.jersey, Jersey 2 uses org.glassfish.jersey). Take a look at this answer and at these articles:

Community
  • 1
  • 1
Michal Gajdos
  • 10,339
  • 2
  • 43
  • 42
  • Thanks for this clarification. I am aware, I wasn't sure which classes to reference in the web.xml. Actually, I got the filter working using com.sun.jersey.spi.container.ContainerRequestFilter instead of javax.ws.rs.container.ContainerRequestFilter. But than its just global and so its useless for my case. I guess that NameBinding for the method doesn't work because I use jersey 1.x. But trying to switch to jersey 2.x put me to major troubles with the project startup in tomcat. Maybe I should try that again and hope it resolves the issues. – ulrich Feb 05 '14 at 17:52
  • Now I created a new clean JAX-RS project only based on Jersey 2. Now I can use javax.ws.rs.container.ContainerRequestFilter and bind it to certain methods of my services. works perfectly now. Thanks!! – ulrich Feb 05 '14 at 19:05
4

Just compiling the answer from Michael Gajdos to help someone who do not want open more tabs:

When you are using Jersey-2 you must use the follow configuration to register your filter into the web.xml

jersey.config.server.provider.classnames

instead of

com.sun.jersey.spi.container.ContainerRequestFilters (jersey-1x)

 <!-- This is the config needed -->
<servlet>    
      //...         
     <init-param>
         <param-name>jersey.config.server.provider.classnames</param-name>
         <param-value>com.your_package_path.yourClassFilter</param-value>
     </init-param>
      //...
</servlet>
Vitorlui
  • 760
  • 1
  • 11
  • 26
0

Have a look at this blog post for the more 'classical' approaches (without using the annotation)

svarog
  • 9,477
  • 4
  • 61
  • 77
ACV
  • 9,964
  • 5
  • 76
  • 81