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