Search code examples
javaservletsjax-rsjersey-client

Object values becomes NULL while passing to the servlet in JAX-RS


JAX-RS using Jersey

I am trying to send an object "Broadcast" from the client to the servlet and print the values in the servlet side. But my output becomes null. Help me with the issue thanks in advance :-)

Servlet

@POST
@Path("/receiverMessage")
public Response sendMessage(Broadcast broadcast) {
    System.out.println(broadcast.getSenderName());
    System.out.println(broadcast.getReceiverName());
    System.out.println(broadcast.getTime());
    return Response.ok().status(200).entity("SUCCESS").build();
}

Client

public class Client {
public static void main(String[] args) {
    Client client = ClientBuilder.newClient();
    Broadcast broadcast = new Broadcast("SENDER", "RECEIVER", new Timestamp(System.currentTimeMillis()));
    Response messagePost = client.target("http://localhost:8081/xyz/abc")
            .path("receiverMessage")
            .request()
            .post(Entity.entity(broadcast, MediaType.APPLICATION_JSON), Response.class);
    System.out.println(messagePost.getStatus());
}}

Broadcast Model

public class Broadcast {
private String senderName;
private String receiverName;
private Timestamp time;
}

MessageBodyWriter

@Override
public void writeTo(Broadcast broadcast, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
    System.setProperty("javax.xml.bind.context.factory","org.eclipse.persistence.jaxb.JAXBContextFactory");
    try {
        JAXBContext context = JAXBContext.newInstance(type);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.marshal(broadcast, entityStream);
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

Output

null 
null
null

Solution

  • If you are using Jersey, then you don't need to do anything extra. Jersey has capabilities to (de)serialize your JSON. But, there are couple of changes you need to do.

    1. Your are missing the @Consumes and @Produces annotations at server side

      @POST
      @Path("/receiverMessage")
      @Consumes ( { MediaType.APPLICATION_JSON })
      @Produces ( { MediaType.TEXT_PLAIN })
      public Response sendMessage(Broadcast broadcast) {
         System.out.println(broadcast.getSenderName());
         System.out.println(broadcast.getReceiverName());
         System.out.println(broadcast.getTime());
         return Response.ok().status(200).entity("SUCCESS").build();
      }
      
    2. Also, your POJO class doesn't have annotation to indicate that is JAXB class. You can find very good example for Using JAX-RS with JAXB