Home » Java » Enterprise Java » Creating a simple JAX-RS MessageBodyWriter

About Mike Miller

Mike is a software developer who loves to learn how things work. A Java programmer who caught the Groovy & Grails itch and is always looking for opportunities to include them as part of the solution.

Creating a simple JAX-RS MessageBodyWriter

JAX-RS is really cool and with the help of JAXB a lot of response data types can be converted for you simply by adding annotating the data objects with JAXB annotations.  I am fairly new at JAXB but some simple cut/paste of annotations will take you a long way.

There maybe some types of data that you can’t or won’t annotate for the purposes of returning that data type from a JAX-RS resource method.   One simple example is returning either a boolean (primitive) or the wrapper Boolean class.   I read a question on StackOverflow where someone asked if they could return a boolean from a resource method and since I didn’t know the answer, I decided to try it!  My version only returns XML, not JSON but you should get the idea.

I started with the Jersey User’s Guide HelloWorld example and starting modifying from there.  I used the pom.xml and the only change was to uncomment a block to allow using JSON.

Main class 

This the main class from the Hello World example without any changes.

package com.example;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import java.io.IOException;
import java.net.URI;

/**
 * Main class.
 *
 */
public class Main {
    // Base URI the Grizzly HTTP server will listen on
    public static final String BASE_URI = "http://localhost:8080/myapp/";

    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in com.example package
        final ResourceConfig rc = new ResourceConfig().packages("com.example");

        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }

    /**
     * Main method.
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
}

Resource class

I created a resource class that included a GET method to return a boolean and another GET method to return the wrapper Boolean class.  Notice the getBool() and getBoolean() methods return XML as the first option.

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public String getIt() {
        return "Got it!";
    }

    @GET
    @Path("/bool")
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public boolean getBool() {
        return false;
    }

    @GET
    @Path("/Boolean")
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public Boolean getBoolean() {
        return Boolean.TRUE;
    }
}

BooleanMessageBodyWriter class

Here’s the interesting part, creating the MessageBodyWriter class to allow the resource method to return XML for the boolean or Boolean.

package com.example;
 
import javax.ws.rs.Produces;
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 javax.ws.rs.WebApplicationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
 
@Provider
@Produces("application/xml")
public class BooleanMessageBodyWriter implements MessageBodyWriter {
  
    @Override
    public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        System.out.println("isWriteable called...");
        return type == Boolean.class;
    }
  
    @Override
    public long getSize(Boolean myBool, Class type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        // deprecated by JAX-RS 2.0 and ignored by Jersey runtime
        return 0;
    }
  
    @Override
    public void writeTo(Boolean myBool,
                        Class type,
                        Type genericType,
                        Annotation[] annotations,
                        MediaType mediaType,
                        MultivaluedMap httpHeaders,
                        OutputStream entityStream)
                        throws IOException, WebApplicationException {
  
        StringBuilder sb = new StringBuilder();
        sb.append("").append(myBool.toString()).append("");
        DataOutputStream dos = new DataOutputStream(entityStream);
        dos.writeUTF(sb.toString());
    }
}

I  haven’t used Maven before but the following targets are all you need to compile and run the project, after installing maven (of course!).

  • mvn compile – compiles the code
  • mvn exec:java – starts the Grizzly HttpServer and deploys the restful service.

Hope this helps!
 

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

One comment

  1. Leonid Ovanesbekov

    Mr. Mike Miller!
    Thank you very much!
    Yours example really help me!

    With best wishes from Russia, Moscow,
    Leonid O

Leave a Reply

Your email address will not be published. Required fields are marked *

*


seven × = 49

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Do you want to know how to develop your skillset and become a ...

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!
Get ready to Rock!
To download the books, please verify your email address by following the instructions found on the email we just sent you.

THANK YOU!

Close