04. MessageBodyReaders and MessageBodyWriters. Custom Media Types

Java Brains is the inspiration for this blog.

1. MessageBody vs Parameters

The message body is the content of the request while the parameters are included in the URL. To read params we need param converters and annotations like @Path, @PathParam, @QueryParam

Let's see 3 scenarios PUT, GET and POST

1.a PUT request

A PUT request is similar

/firstapi/users/ximo where "ximo" is a Path Parameter

And then is a body data (for instance JSON data) used to update the user

 {"data": "...." }

1.b GET request

A GET request only has params (Path Params and/or Query Params)

/fistapi/getusers/user?start=20&size=10   where getuser is a Path Param and start and size are Query Params

No body message is used in a GET


1.c POST request

A POST request to create a new user

/firstapi/users

header-info with header params (usually for security information)

Body message with JSON data (in this case)   {"userdata": "...."}


2. Creating a Message Body Writer

First, let's create a resource class that produces "text/plain" but returns a Date type


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package org.ximodante.jaxrs;

import java.util.Calendar;
import java.util.Date;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("test04")
public class MyResource04 {
  
 @GET
 @Produces(MediaType.TEXT_PLAIN)
 public Date testMethod() {
  return Calendar.getInstance().getTime();
 }
}

If the application is executed, an error is raised as it needs a MessageBodyWriter to translate Date to "text/plain". Here is the class


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package org.ximodante.jaxrs;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Date;
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;


@Provider
@Produces(MediaType.TEXT_PLAIN)
public class MyMessageBodyWriter04 implements MessageBodyWriter<Date>{

 @Override
 public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
  return Date.class.isAssignableFrom(type);
 }

 @Override
 public void writeTo(Date t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
   MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
   throws IOException, WebApplicationException {
  entityStream.write(t.toString().getBytes());
 }
}

Don't forget to use the annotations and fill the 2 methods imposed by the interface and the annotations @Provider and @Produces.

The result is:




3. Creating Custom Media Types

In case we want to create new media type, we can reuse the MyResources04 class and change line 14 with:

@Produces(MediaType.TEXT_PLAIN, "text/shordate")

Where "text/shortdate" is a new type we have invented.
But now we need another new MessageBodyWriter class that in line 17 has:

@Produces("text/shortdate")

and the method writeTo that may have a different line 29, for instance:

entityStream.write(("Ximo Dante:" + t.toString()).getBytes());

It is interesting watching the JavaBrains video on how to use with Postman the different ty7pes of responses.


Comentarios

Entradas populares de este blog

03. Param annotations, and param converters

01. Let's go! Creating a Java Project