Monday, August 31, 2015

A simple CSV MessageBodyWriter for JAX-RS using Jackson

This is a very simple MessageBodyWriter that will allow you to output a List of objects as CSV from a JAX-RS webservice. Such services can be useful with frameworks such as D3.js. Jackson provides MessageBodyWriters for several formats, but it does not provide an out of the box solution for CSV. It does however offer several useful  classes to serialize objects into CSV. These are provided in the jackson-dataformat-csv artifact.
We can use those classes to create our own CSV MessageBodyWritter as shown below:
package csv;


import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;

@Provider
@Produces("text/csv")
public class CSVMessageBodyWritter implements MessageBodyWriter {

    @Override
    public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        boolean ret=List.class.isAssignableFrom(type);
        return ret;
    }

    @Override
    public long getSize(List data, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) {
        return 0;
    }

    @Override
    public void writeTo(List data, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap multivaluedMap, OutputStream outputStream) throws IOException, WebApplicationException {
        if (data!=null && data.size()>0) {
            CsvMapper mapper = new CsvMapper();
            Object o=data.get(0);
            CsvSchema schema = mapper.schemaFor(o.getClass()).withHeader();
            mapper.writer(schema).writeValue(outputStream,data);
        }


    }

}
To use our MessageBodyWriter, it must be registered. This can achieved in several ways, depending on your JAX-RS implementation. Normally Jersey and other JAX-RS implementations are configured to scan packages and look for resources. In such cases classed marked with @Provider will be registered automatically. In other cases, the registration will have to be done manually. For example in Dropwizard, you have to manually register the Writer at startup:
 @Override
    public void run(MyConfiguration configuration,
                    Environment environment) {
      
        environment.jersey().register(new CSVMessageBodyWritter());
    }
Once registered, it becomes trivial to have a web service that outputs CSV. It's just a matter of annotating your webservice with the same media type as the MessageBodyWritter: @Produces("text/csv").
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.List;

@Path("/status")
public class StatusResource {
    @GET
    @Produces("text/csv")
    public List<Data> getData() {
        List<Data> data= service.getStatus();
        return data;
    }
}
Our data class is just a normal POJO:
public class Data {
    private String date;
    private Integer minimum;
    private Integer maximum;
    private Integer average;

    public Data() {

    }

    //Getters and setters as needed
}
The output will look like this:
average,date,maximum,minimum
90,3/1856,125,0
60,2/1856,115,16
60,4/1856,115,16

This is a very simple implementation, but should be a good starting point. It's worth nothing that CSV is inherently limited, and can't easily represent hierarchical object graphs. Therefore you might need flatten your data before exporting to CSV. If you need to ingest a CSV in a webservice, you can follow a similar approach to create a MessageBodyReader that will create an object from a CSV stream.

Tuesday, August 25, 2015

Simple Scala dependency injection with Scaldi (part 1)


Dependency Inject is a very useful pattern in most medium to larger projects. However, it's also sometimes useful in smaller projects. In smaller projects, I normally prefer to use appropriately smaller frameworks. In the case of Scala, Scaldi provides a very lightweight dependency injection mechanism.
Whenever I try to learn a new framework, I always like to learn my way up from a very simple example. The following is close to the absolute minimum example I could write to get Scaldi working. From this very simple example I will continue to add other useful features, such as testing and integration with other frameworks.

The build.sbt is very simple, we just added a single dependency:
name := "scaldi-test"

version := "1.0"

scalaVersion := "2.11.6"

libraryDependencies += "org.scaldi" %% "scaldi" % "0.5.6"
The main Scala file is shown next, and contains all of the necessary parts to get Scaldi working:
import scaldi.{Injector, Injectable, Module}

object HelloScaldi {
  def main(args: Array[String]) {

    val test=new Test;
    test.run
  }
}

class Test( )  extends Injectable {
  def run: Unit = {
    implicit  val injector:Injector = new UserModule //1
    val output:IService=inject[IService] //2
    println(output.execute("Scaldi"));
  }
}

class UserModule extends Module { //3
  bind [ITransport] to new MessageTransport //4
  bind [IService] to  new MessageService(inject[ITransport]) //5

}

trait ITransport {
  def send(s: String)
}

trait IService {
  def execute(x: String): String
}

class MessageService(transport:ITransport) extends IService {

  override def execute(x: String): String = {
    val ret="Hello " + x
    transport.send(ret)
    return  ret
  }
}

class MessageTransport() extends ITransport {
  override def send(s: String) = println("Sending message: " + s)
}




  1. In this line, we create an Injector using a new UserModule. The injector is the entry point into the DI container. The Module defines the bindings that will be using for the injection
  2. The inject method uses the implicit Injector to provide us with the object bound to trait IService.
  3. The Module provides explicit bindings.
  4. In this line, we bind ITransport to a new instance of MessageTransport
  5. The trait IService is bound to a new instance of MessageService, in which we're injecting ITransport. This allows us to keep MessageService and MessageTransport decoupled.
This simple example can be executed using sbt:
sbt run
The output will look something like this:
[info] Running HelloScaldi 
Sending message: Hello Scaldi
Hello Scaldi
[success] Total time: 2 s, completed Aug 25, 2015 7:40:23 PM

As you can see, the example is very simple, but if you want to start from the ground up, hopefully this will give you a good starting point. If you have any questions, don't hesitate to leave a comment.
You can check out the full source code here.