Marshaling Java objects to the CSV representation with MessageBodyWriter

The JAX-RS framework uses MessageBodyWriter to serialize the Java representation of resources returned by the REST web API into an appropriate format, which is sent back to the client. The JAX-RS runtime natively supports the serialization of the commonly used Java types, such as java.lang.String, java.io.InputStream, and Java custom objects annotated with JAXB binding annotations. You can provide your own implementation of MessageBodyWriter if you find that the default implementation provided by JAX-RS is not meeting your use case requirements.

A javax.ws.rs.ext.MessageBodyWriter<T> provider should implement the following methods:

  • isWriteable(): This method checks whether this MessageBodyWriter implementation supports converting the Java type present in the method argument to the designated internet media type. This method is invoked when the framework tries to find a MessageBodyWriter implementation for serializing the Java objects returned by a resource method to the designated internet media type.
  • getSize(): JAX-RS 2.0 deprecated this method, and the value returned by the method is ignored by the JAX-RS runtime. You can return -1 from this method.
  • writeTo(): This method writes a Java type object to an HTTP message.

Keep a note of the following points when building a MessageBodyWriter implementation:

  • A MessageBodyWriter provider implementation may be annotated with @Produces to restrict the media types for which it will be considered suitable
  • A MessageBodyWriter provider implementation must be either programmatically registered in the JAX-RS runtime or must be annotated with @Provider annotation
The API documentation for MessageBodyWriter is available at https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/MessageBodyWriter.html.

The following example shows how you can build a custom MessageBodyWriter implementation that converts a list of the Department Java objects into the CSV format:

//Other imports omitted for brevity 
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 org.supercsv.io.CsvBeanWriter; 
import org.supercsv.io.ICsvBeanWriter; 
import org.supercsv.prefs.CsvPreference; 
 
@Provider 
@Produces("application/csv") 
public class CSVMessageBodyWriter implements MessageBodyWriter<List<Department>> { 
 
    /** 
     * Ascertain if MessageBodyWriter supports 
     * a particular type. 
     */ 
    @Override 
    public boolean isWriteable(Class<?> type, Type genericType,  
        Annotation[] annotations, MediaType mediaType) { 
        //Is this MessageBodyWriter implementation capable  
        //of serializing the object type returned by  
        //the current REST API call? 
        return (List.class.isAssignableFrom(type)); 
    } 
 
    /** 
     *Deprecated by JAX-RS 2.0 and ignored by Jersey runtime 
     */ 
    @Override 
    public long getSize(List<Department> t, Class<?> type, Type  
        genericType, Annotation[] annotations,  
            MediaType mediaType) { 
        return 0; 
    } 
 
    /** 
     * Converts Java to desired media type and Writes it  
     * to an HTTP response 
     */ 
    @Override 
    public void writeTo(List<Department> dataList, Class<?> type,  
        Type genericType, Annotation[] annotations, MediaType 
            mediaType, MultivaluedMap<String, Object> httpHeaders,  
                OutputStream entityStream) throws IOException,  
                    WebApplicationException { 
        // This class uses CsvBeanWriter for converting  
        // Java to CSV. It is an open source framework  
        // that writes a CSV file by mapping each field  
        // on the bean to a column in the CSV file  
        //(using the supplied name mapping). 
        ICsvBeanWriter writer = new CsvBeanWriter( 
            new PrintWriter(entityStream),  
                CsvPreference.STANDARD_PREFERENCE); 
        //No data then return         
        if (dataList == null || dataList.size() == 0) { 
            return; 
        } 
        //Columns headers in CSV 
        String[] nameMapping ={"departmentId","departmentName", 
        "managerId","locationId"} ; 
 
        //CsvBeanWriter writes the header with the property names   
        writer.writeHeader(nameMapping); 
        for (Object p : dataList) { 
            //Write each row 
            writer.write(p, nameMapping); 
        } 
        writer.close(); 
    } 
} 

The following RESTful web service call illustrates a sample output (in CSV format) generated by the CSVMessageBodyWriter implementation:

GET /api/hr/departments HTTP/1.1 
Host: localhost:8080 
Accept: application/csv 
 
departmentId,departmentName,locationId,managerId 
1001,"Finance",1700,101 
1002,"Office Administration",1500,205 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.135.249