How can I add a custom filter for my rest resources' requests/responses?

Glenn Verrijkt December 21, 2014

Hello,

 

I have a custom JIRA plugin that includes some rest resources and that also acts as a client for those resources.

I would like to add some filters to add common processing for all requests/responses (e.g. logging). This is typical for a Jersey rest api, so normally I'd have to define my own classes that implement ContainerRequestFilter and/or ContainerResponseFilter and add a @Provider annotation.

The REST Plugin Module documentation mentions that the plugin will scan my classes for @Provider annotations, but for some reasons my filters do not execute.

Is there any configuration I need to add to my atlassian-plugin.xml to make filters work? 

I develop for JIRA 6.1, which contains rest-api-module 2.8.0-m8 and uses Jersey 1.18.3.

 

Preferably I'd also add some filters on the client side. I use SAL's RequestFactory to send requests, but this does not seem to provide any functionality to add filters. Is there a way to do this?

 

Any help appreciated

1 answer

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

5 votes
Answer accepted
Glenn Verrijkt December 28, 2014

This is what I ended up with:

Server side filters 

See the Jersey 1.18 javadoc of the com.sun.jersey.api.container.filter package.

There are 2 kinds of filters: Container filters and Resource filters.

I didn't find a way to get a working Container filter. These require you to set some init-params on your Jersey servlet or filter, but I assume that Atlassian hides that configuration part for plugin developers, so you cannot set them.

Resource filters however, work fine. For example, you can create your own filter by implementing the ResourceFilter interface like so:

public class MyFilter implements ResourceFilter, ContainerRequestFilter, ContainerResponseFilter {
    @Override
    public ContainerRequest filter(ContainerRequest containerRequest) {
        // Do something with the incoming request here
        return containerRequest;
    }
    @Override
    public ContainerResponse filter(ContainerRequest containerRequest, ContainerResponse containerResponse) {
        // Do something with the outgoing response here
        return containerResponse;
    }
    @Override
    public ContainerRequestFilter getRequestFilter() {
        return this;
    }
    @Override
    public ContainerResponseFilter getResponseFilter() {
        return this;
    }
}

 

And now you can annotate your rest method with it:

@Path("/myresource")
public class MyResource {

    @POST
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
    @ResourceFilters(MyFilter.class)
    public MyValue createSomething(MyValue myValue) {
        // do things here
    }
}

Whenever a request is sent to /myresource, MyFilter will process the request and response.

Client side filters

The RequestFactory of the SAL api does not expose Jersey client, so there is no way to access Jersey's features. If you want filter functionality you have to implement your own mechanism to do so.

Mikhail_Kopylov
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 1, 2016

@Glenn Verrijkt, thanks for your answer. 

Is there a way to register a ResourceFilterFactory in JIRA to register a filter for all methods?

Saurabh Gupta August 4, 2017

I am trying to inject my dao class in the filter, its getting injected nicely in the rest class but not in the filter class. 

Tormod Haugene March 15, 2019

So we are basically "highjacking" a ResourceFilter with additional Request/Response filters. Well thought out! 

Also, it works like a charm for Jira 7.13. Thanks!

Like Glenn Verrijkt likes this
TAGS
AUG Leaders

Atlassian Community Events