· neo4j

neo4j Unmanaged Extension: Creating gzipped streamed responses with Jetty

I recently wrote a blog post describing how we created a streamed response and the next thing we wanted to do was gzip the response to shrink it's size a bit.

A bit of searching led to GZIPContentEncodingFilter popping up a lot of times but this is actually needed for a client processing a gripped response rather than helping us to gzip a response from the server.

I noticed that there was a question about this on the mailing list from about a year ago although Michael pointed out that the repository has now moved and the example is available here instead.

I adapted the example a bit and ended up with the following lifecycle plugin:

package com.markandjim;

public class GZipInitialiser implements SPIPluginLifecycle {
    private WebServer webServer;

    public Collection<Injectable<?>> start(NeoServer neoServer) {
        webServer = getWebServer(neoServer);
        GzipFilter filter = new GzipFilter();

        webServer.addFilter(filter, "/*");
        return Collections.emptyList();


    private WebServer getWebServer(final NeoServer neoServer) {
        if (neoServer instanceof AbstractNeoServer) {
            return ((AbstractNeoServer) neoServer).getWebServer();
        throw new IllegalArgumentException("expected AbstractNeoServer");

    public Collection<Injectable<?>> start(GraphDatabaseService graphDatabaseService, Configuration configuration) {
        throw new IllegalAccessError();

    public void stop() {


I then added the following line to 'resources/META-INF/services/org.neo4j.server.plugins.PluginLifecycle:


After compiling that and deploying the JAR to the 'plugins' I tried calling the end point using cURL:

$ curl -H "Accept-Encoding:gzip,deflate" -v  http://localhost:7474/unmanaged/subgraph/1000/1
* About to connect() to localhost port 7474 (#0)
*   Trying ::1...
* Connection refused
*   Trying
* connected
* Connected to localhost ( port 7474 (#0)
> GET /unmanaged/subgraph/1000/1 HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: localhost:7474
> Accept: */*
> Accept-Encoding:gzip,deflate
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Access-Control-Allow-Origin: *
< Content-Encoding: gzip
< Transfer-Encoding: chunked
< Server: Jetty(6.1.25)



The GZIPContentEncodingFilter that I mentioned earlier comes in handy if we want to call the end point from a Jersey client:

public class Neo4jJerseyClient {
    public static void main(String[] args) {
        Client client = Client.create();
        client.addFilter(new GZIPContentEncodingFilter(false));

        WebResource webResource = client.resource("http://localhost:7474/unmanaged/subgraph/1000/1");

        ClientResponse response  = webResource.header("accept-encoding", "gzip,deflate").get(ClientResponse.class);

        System.out.println("response = " + response.getEntity(String.class));

We could also call it using HTTParty from the land of Ruby:

response = HTTParty.get("http://localhost:7474/unmanaged/subgraph/1000/1", 
  :headers => { 'Accept-Encoding' => 'gzip,deflate' } )

p response
  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket