If there are more than one Filters in our application, then we may want to have them executed in a particular order.
An order can be specified by using @Priority annotation. This annotation accepts an integer parameter.
If @Priority annotation is used properly, the providers are sorted in ascending order; the lower the number the higher the priority.
Let's see an example how to use @Priority for filter.
Example
Implementing Filter
This filter will record the time taken for executing a resource method.
@Priority(1)
@Provider
public class TimeFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext reqContext) throws IOException {
System.out.println("-- TimeFilter request --");
reqContext.setProperty("start-time", System.currentTimeMillis());
}
@Override
public void filter(ContainerRequestContext reqContext,
ContainerResponseContext resContext) throws IOException {
System.out.println("-- TimeFilter response --");
long startTime = (long) reqContext.getProperty("start-time");
System.out.printf("Time taken for request %s: %s milli secs%n",
reqContext.getUriInfo().getPath(),
System.currentTimeMillis() - startTime
);
}
}
A log filter:
@Priority(2)
@Provider
public class LogFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext reqContext) throws IOException {
System.out.println("-- req headers --");
log(reqContext.getUriInfo(), reqContext.getHeaders());
}
@Override
public void filter(ContainerRequestContext reqContext,
ContainerResponseContext resContext) throws IOException {
System.out.println("-- res headers --");
log(reqContext.getUriInfo(), resContext.getHeaders());
}
private void log(UriInfo uriInfo, MultivaluedMap<String, ?> headers) {
System.out.println("Path: " + uriInfo.getPath());
headers.entrySet().forEach(h -> System.out.println(h.getKey() + ": " + h.getValue()));
}
}
A JAX-RS resource
@Path("/")
public class MyResource {
@GET
@Path("{path:.*}")
public String getResponse(@PathParam("path") String path) {
System.out.printf("creating response for '%s'%n", path);
return "dummy-response for " + path;
}
}
To try examples, run embedded tomcat (configured in pom.xml of example project below):
mvn tomcat7:run-war
Output
Using HTTPie to access the resource:
Output on the server console:
-- TimeFilter request --
-- req headers --
Path: customers
host: [localhost:8080]
connection: [keep-alive]
accept-encoding: [gzip, deflate]
accept: [*/*]
user-agent: [HTTPie/0.9.9]
creating response for 'customers'
-- res headers --
Path: customers
Content-Type: [text/plain]
-- TimeFilter response --
Time taken for request customers: 13 milli secs
As seen in above output, TimeFilter ran before LogFilter. Reversing the priories will reverse the execution order of the filters as well.
Example ProjectDependencies and Technologies Used: - jersey-server 2.25.1: Jersey core server implementation.
- jersey-container-servlet 2.25.1: Jersey core Servlet 3.x implementation.
- JDK 1.8
- Maven 3.3.9
|