Request and Response Filters in Dropwizard

When constructing a Dropwizard application, there may be some pre-processing or post-processing you’d like to do on Resource methods. It’s fairly easy to add request and response filters in Dropwizard through the implementation of ContainerRequestFilter, ContainerResponseFilter, and ResourceFilterFactory, and adding them to the environment.

Request and Response Filters

The container filters will review every request and response, and can review properties of the request or response to determine behavior. For example, say we want to validate a specific query parameter when its present:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class MyCustomRequestFilter implements ContainerRequestFilter {
@Override
public ContainerRequest filter(ContainerRequest request) {
if (request.getQueryParameters().containsKey("validateMeParam")) {
List paramValues = request.getQueryParameters().get("validateMeParam");
/* validation logic */
}
// finished validation
return request;
}
}
public class MyCustomRequestFilter implements ContainerRequestFilter { @Override public ContainerRequest filter(ContainerRequest request) { if (request.getQueryParameters().containsKey("validateMeParam")) { List paramValues = request.getQueryParameters().get("validateMeParam"); /* validation logic */ } // finished validation return request; } }
public class MyCustomRequestFilter implements ContainerRequestFilter {
    @Override
    public ContainerRequest filter(ContainerRequest request) {

        if (request.getQueryParameters().containsKey("validateMeParam")) {
            List paramValues = request.getQueryParameters().get("validateMeParam");

            /* validation logic */
        }

        // finished validation
        return request;
    }
}

Then, add that filter to the environment in your Application.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
environment.getJerseyResourceConfig().getContainerRequestFilters().add(MyCustomRequestFilter.class);
environment.getJerseyResourceConfig().getContainerRequestFilters().add(MyCustomRequestFilter.class);
environment.getJerseyResourceConfig().getContainerRequestFilters().add(MyCustomRequestFilter.class);

Remember, this runs on every request and response, so be sure you want to run whatever checks you are running.

Filter Factories

Implementing the ResourceFilterFactory allows you to programmatically add request and response filters. The filters will then only run when applicable. Continuing in the validating of a specific parameter, let’s assume I have the annotation ValidateParams, which can be applied at the method or class level. The following implementation will look at each resource method when the application starts, and run the create method. If the annotation is present, the aforementioned MyCustomRequestFilter will be used.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class MyCustomResponseFilterFactory implements ResourceFilterFactory {
@Override
public List<ResourceFilter> create(AbstractMethod am) {
List<ResourceFilter> filtersAppliedToMethod = new ArrayList<ResourceFilter>();
// get the annotation from the method
ValidateParams ann = am.getAnnotation(ValidateParams.class);
// if the method does not have the annotation, check the class
if (ann == null) {
ann = am.getMethod().getDeclaringClass().getAnnotation(ValidateParams.class);
}
// if the annotation is present, add the filter to the method
if (ann != null) {
filtersAppliedToMethod.add(new ValidateParamFilter());
}
return filtersAppliedToMethod;
}
/**
* A factory object for creating ResponseFilters.
*/
protected class ValidateParamFilter implements ResourceFilter {
@Override
public ContainerRequestFilter getRequestFilter() {
return new MyCustomRequestFilter();
}
@Override
public ContainerResponseFilter getResponseFilter() {
// no response filter needed
return null;
}
}
}
public class MyCustomResponseFilterFactory implements ResourceFilterFactory { @Override public List<ResourceFilter> create(AbstractMethod am) { List<ResourceFilter> filtersAppliedToMethod = new ArrayList<ResourceFilter>(); // get the annotation from the method ValidateParams ann = am.getAnnotation(ValidateParams.class); // if the method does not have the annotation, check the class if (ann == null) { ann = am.getMethod().getDeclaringClass().getAnnotation(ValidateParams.class); } // if the annotation is present, add the filter to the method if (ann != null) { filtersAppliedToMethod.add(new ValidateParamFilter()); } return filtersAppliedToMethod; } /** * A factory object for creating ResponseFilters. */ protected class ValidateParamFilter implements ResourceFilter { @Override public ContainerRequestFilter getRequestFilter() { return new MyCustomRequestFilter(); } @Override public ContainerResponseFilter getResponseFilter() { // no response filter needed return null; } } }
public class MyCustomResponseFilterFactory implements ResourceFilterFactory {
    @Override
    public List<ResourceFilter> create(AbstractMethod am) {

        List<ResourceFilter> filtersAppliedToMethod = new ArrayList<ResourceFilter>();

        // get the annotation from the method
        ValidateParams ann = am.getAnnotation(ValidateParams.class);

        // if the method does not have the annotation, check the class
        if (ann == null) {
            ann = am.getMethod().getDeclaringClass().getAnnotation(ValidateParams.class);
        }

        // if the annotation is present, add the filter to the method
        if (ann != null) {
            filtersAppliedToMethod.add(new ValidateParamFilter());
        }

        return filtersAppliedToMethod;
    }

    /**
     * A factory object for creating ResponseFilters.
     */
    protected class ValidateParamFilter implements ResourceFilter {

        @Override
        public ContainerRequestFilter getRequestFilter() {
            return new MyCustomRequestFilter();
        }

        @Override
        public ContainerResponseFilter getResponseFilter() {
            // no response filter needed
            return null;
        }
    }
}

Then, add this factory to the environment in your Application.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
environment.getJerseyResourceConfig().getResourceFilterFactories().add(ResponseProducerFactory.class);
environment.getJerseyResourceConfig().getResourceFilterFactories().add(ResponseProducerFactory.class);
environment.getJerseyResourceConfig().getResourceFilterFactories().add(ResponseProducerFactory.class);