Damion Brown's Blog


Java REST API with Jackson Annotations and Jackson JSON

  • Fri 23 March 2018
  • Tech

In extension to the previous post about Java RESTful APIs with JAX-RS, Jetty, and Jersey two additional libraries provide critically useful functionality: Jackson Annotations & JSON provider .

Jackson Annotations allows us to tag fields within a class as mappable properties of a corresponding datatype, IE: JSON. In other wording, we can bind Java Objects to JSON Objects 1:1 using only annotations. (See "SimpleModel.java" below.)

Jackson JSON Provider works with Jackson Annotation as a provider of Java<->JSON Readers/Writers. You'll need this to serve MediaType.APPLICATION_JSON to HTTP Clients. (See "HelloJsonApp.java" below.)

Github repo of the full working sourcecode can be found here.

Application.java: (Source)

This is the same Jetty application supplier described in more detail in the previous post referenced above.

// Construct a server
final Server server = new Server(new InetSocketAddress("localhost", 8080));

ServletContextHandler handler = new ServletContextHandler();
ServletHolder helloJsonServlet = new ServletHolder(new ServletContainer(new HelloJsonApp()));

// Required symbol '*' grants scope to servlet application.
handler.addServlet(helloJsonServlet, "/app2/*");


// start the server
try {
} catch (Exception e) {
        // TODO Auto-generated catch block

HelloJsonApp.java: (Source)

This JAX-RS Application loads the JacksonJsonProvider via c.add(JacksonJsonProvider.class);

This makes MediaType.APPLICATION_JSON available for usage.

public class HelloJsonApp extends Application {
        private final Set<Class<?>> classes;

        public HelloJsonApp() {
                System.out.println("HelloJsonApp Contruct");
                HashSet<Class<?>> c = new HashSet<Class<?>>();
                 * com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
                 * Binder for JSON<->POJO, this providers readers and writers for
                 * MediaType.APPLICATION_JSON
                classes = Collections.unmodifiableSet(c);

        public Set<Class<?>> getClasses() {
                return classes;


HelloJson.java: (Source)

The method getModel(@PathParam("id") int id) recieves the id from{id} and returns a JSON object retrieved from SimpleModel via ModelHolder.

The JSON object will be the HTTP response to the query. This is all automatically hanlded by the @Annotations.

public class HelloJson {

        public String heyjson() {
                return "Hey JSON!";

        @Produces({ MediaType.APPLICATION_JSON })
        public Response getModel(@PathParam("id") int id) {

                SimpleModel sm = ModelHolder.getHolder().getSimpleModel(id);

                if (sm == null) {
                        return Response.status(Status.NOT_FOUND).build();

                return Response.ok(sm).build();

        @Produces({ MediaType.TEXT_PLAIN })
        public Response setModel(@PathParam("id") int id, @PathParam("string") String string) {

                ModelHolder.getHolder().setSimpleModel(new SimpleModel(id, string));

                return Response.ok("OK").build();

SimpleModel.java: (Source)

This is our Java Object <-> JSON Object. We can return this SimpleModel as seen in HelloJson.java and it will automagically be converted to JSON.

Additioanlly, we can recieve a JSON Object via HTTP and pass it as a SimpleModel Java Object. Super cool stuff.

public class SimpleModel {

        public SimpleModel(int id, String string) {
                this.id = id;
                this.string = string;

        private int id;
        private String string;

        public int getId() {
                return id;

        public void setId(int id) {
                this.id = id;

        public String getString() {
                return string;

        public void setString(String string) {
                this.string = string;


ModelHolder.java: (Source)

This is part of the demonstration code - it holds multipul SimpleModel Java Objects and aids in exampling how JSON<->JAVA Object handling works.

It must be accessed statically as Jersey loads our JAX-RS Application from a Set<Class> and thus it is not possible to pass objects in constructors.

public class ModelHolder {

        private HashMap<Integer, SimpleModel> SimpleModelHolder;

        static ModelHolder mh;

        public ModelHolder() {
                System.out.println("ModelHolder Constructed");
                this.SimpleModelHolder = new HashMap<Integer, SimpleModel>();
                ModelHolder.mh = this;

        public SimpleModel getSimpleModel(int id) {
                for (Integer i : SimpleModelHolder.keySet()) {
                        System.out.println(i + " : " + SimpleModelHolder.get(i).getString());
                if (SimpleModelHolder.containsKey(id)) {
                        return SimpleModelHolder.get(id);
                return null;

        public void setSimpleModel(SimpleModel simpelModel) {
                SimpleModelHolder.put(simpelModel.getId(), simpelModel);

         * Gets a ModelHolder or creates one if none exists.
         * @return instanceof ModelHodler.
        public static ModelHolder getHolder() {
                if (mh == null) {
                        new ModelHolder();
                return ModelHolder.mh;