Creating Custom JAX-RS MessageBodyReader

You can use a JAX-RS MessageBodyReader to deserialize an entity on the server or client. Jersey already provides default deserializers like json and xml. This is just a demonstration how you can build your own deserializer.

JAX-RS MessageBodyReader

We consume a User entity in xml representation.

package com.memorynotfound.jaxrs.chunked;

import javax.ws.rs.*;

@Path("/users")
public class UserResource {

    @POST
    @Consumes("application/xml")
    public void getUser(User user){
        System.out.println(user);
    }

}

Here is the JAX-B mapping of the entity we are consuming.

package com.memorynotfound.jaxrs.chunked;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User {

    private Integer id;
    private String name;

    public User() {
    }

    public User(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

We create our deserializer by implementing the MessageBodyReader interface and override the appropriate methods. The isReadable method inspects if the deserializer is able to process the entity. The readFrom() method does the real deserialization into a java object.

package com.memorynotfound.jaxrs.chunked;

import javax.ws.rs.Consumes;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

@Provider
@Consumes("application/xml")
public class UserMessageBodyReader implements MessageBodyReader<User> {


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

    @Override
    public User readFrom(Class<User> type, Type genericType, Annotation[] annotations,
                         MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
                         InputStream entityStream) throws IOException, WebApplicationException {

        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
            return (User) jaxbContext.createUnmarshaller().unmarshal(entityStream);
        } catch (JAXBException e) {
            throw new ProcessingException("Error deserializing user.", e);
        }
    }
}

Demo

When make a HTTP POST with the following xml message body to the resource: http://localhost:8081/jaxrs-message-body-reader/api/users.

<user>
  <id>1</id>
  <name>John Doe</name>
</user>

We print the following output to the console, indicating that the request is successfully parsed.

User{id=1, name='John Doe'}

References

Download

You may also like...