users@jersey.java.net

Re: [Jersey] need code samples for hooking in converters

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 17 Jun 2008 11:03:27 +0200

Hi Mark,

Below is a stand alone example that may help you. I recommend you load
it into an IDE and run a debug session.

You will need to include the following jars in the classpath:

   asm-3.1.jar
   http.jar
   jersey.jar
   jsr311-api.jar

Hope this helps,
Paul.

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
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.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class Main {

     public static class Car {
         public String type;

         public Car(String type) { this.type = type; }
     }

     @Provider
     public static class CarReaderWriter implements
             MessageBodyReader<Car>, MessageBodyWriter<Car> {

         public boolean isReadable(Class<?> c, Type t, Annotation[] as) {
             return Car.class == c;
         }

         public Car readFrom(Class<Car> c, Type t, Annotation[] as,
                 MediaType mt, MultivaluedMap<String, String> headers,
                 InputStream entity) throws IOException,
WebApplicationException {
             try {
                 DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
                 Document d = dbf.newDocumentBuilder().parse(entity);
                 Element e = d.getDocumentElement();
                 return new Car(e.getFirstChild().getNodeValue());
             } catch (SAXException ex) {
                 throw new WebApplicationException(400);
             } catch (ParserConfigurationException ex) {
                 throw new WebApplicationException(500);
             }
         }

         public boolean isWriteable(Class<?> c, Type t, Annotation[] as) {
             return Car.class == c;
         }

         public long getSize(Car car) {
             return -1;
         }

         public void writeTo(Car car, Class<?> c, Type t, Annotation[] as,
                 MediaType mt, MultivaluedMap<String, Object> headers,
                 OutputStream entity) throws IOException,
WebApplicationException {
            OutputStreamWriter osw = new OutputStreamWriter(entity);
            osw.write("<car>");
            osw.write(car.type);
            osw.write("</car>");
            osw.flush();
         }
     }

     @Path("/car")
     public static class CarResource {

         @GET
         public Car get() {
             return new Car("ferrari");
         }

         @POST
         public Car transform(Car c) {
             if (!c.type.startsWith("porsche"))
                 return new Car("porsche");
             else
                 return c;
         }
     }

     public static void client() throws Exception {
         ClientConfig cc = new DefaultClientConfig();
         cc.getProviderClasses().add(CarReaderWriter.class);
         Client c = Client.create(cc);
         WebResource r = c.resource("http://localhost:9999/");

         assertEquals("ferrari", r.path("car").get(Car.class).type);

         assertEquals("porsche 311", r.path("car").post(Car.class, new
Car("porsche 311")).type);
         assertEquals("porsche", r.path("car").post(Car.class, new
Car("trabunt")).type);
     }

     public static void assertEquals(Object o1, Object o2) {
         if (!o1.equals(o2)) {
             System.out.println(o1 + " != " + o2);
             throw new RuntimeException();
         }
     }

     public static void main(String[] args) throws Exception {
         HttpServer s = HttpServerFactory.create("http://localhost:9999/");
         s.start();

         try {
             client();
         } finally {
             s.stop(0);
         }
     }
}

Paul Sandoz wrote:
> Mark Volkmann wrote:
>> Where can I read about configuring message body readers and writers?
>
> Please look at the links that Jakub gave you, and also look at the
> example code for the EntityProvider example distributed with Jersey.
>
>
>> I'm guessing that I need to configure a mapping between Java classes
>> and their corresponding readers and writers somewhere. For example, if
>> I'm working with a Java class called Car that has fields like make,
>> model and year, do I need to configure the reader and writer that
>> handles creating a Car object from XML and creating XML from a Car
>> object?
>>
>
> You would need to develop code to write an instance of Car to XML and
> vice versa. That code is encapsulated in MessageBodyReader and
> MessageBodyWriter implementations respectively. An existing mapping that
> is already implemented is that for JAXB objects to/from XML and JSON.
>
> Skeleton code may look like this:
>
> @ProduceMime("application/xml")
> @ConsumeMime("application/xml")
> @Provider
> public class CarReaderWriter
> implements MessageBodyReader<Car>, MessageBodyWriter<Car> {
> public boolean isReadable(Class<?> type, Type genericType,
> Annotation annotations[]) {
> return Car.class == type;
> }
>
> public boolean isWriteable(Class<?> type, Type genericType,
> Annotation annotations[]) {
> return Car.class == type;
> }
> ...
> }
>
>
> @Path("/")
> @ProduceMime("application/xml")
> public class CarResource {
> @GET
> public Car getCar() {
> Car c = ...
> return c;
> }
> }
>
> Paul.
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109