Search |
||
Integrating Jersey and AbderaPosted by mhadley on February 5, 2008 at 11:38 AM PST
I'm working on an internal project that involves adding Atom Publishing Protocol support to a data store. Naturally, I'm using Jersey for the HTTP side of things and decided to give Apache Abdera a try for simplifying working with feeds and entries. With JAX-RS I can write a feed resource pretty easily: import java.net.URI;
import java.util.Date;
import javax.ws.rs.ConsumeMime;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.UriParam;
import javax.ws.rs.core.HttpContext;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
@ProduceMime("application/atom+xml")
@ConsumeMime("application/atom+xml")
@Path("myfeed")
public class FeedResource {
@HttpContext
private UriInfo uriInfo;
@GET
public Feed getFeed() {
Feed f = AbderaSupport.getAbdera().getFactory().newFeed();
f.setTitle("...");
f.setId(...);
f.addAuthor(...);
f.setUpdated(...);
URI feedLink = uriInfo.getRequestUri();
f.addLink(feedLink.toString(),"self");
for (...) {
Entry e = f.addEntry();
URI entryLink = ...
f.addLink(entryLink.toString(),"alternate");
...
}
return f;
}
@POST
public Response addEntry(Entry e) {
Entry newEntry = AbderaSupport.getAbdera().newEntry();
URI entryLink = ...;
...
return Response.created(entryLink).entity(newEntry).build();
}
}
The To allow use of Abdera's import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.ws.rs.ProduceMime;
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 org.apache.abdera.Abdera;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
@Provider
@ProduceMime("application/atom+xml")
@ConsumeMime("application/atom+xml")
public class AbderaSupport implements MessageBodyWriter<Object>,
MessageBodyReader<Object> {
private final static Abdera abdera = new Abdera();
public static Abdera getAbdera() {
return abdera;
}
public long getSize(Object arg0) {
return -1;
}
public boolean isWriteable(Class<?> type) {
return (Feed.class.isAssignableFrom(type) || Entry.class.isAssignableFrom(type));
}
public void writeTo(Object feedOrEntry, MediaType mediaType,
MultivaluedMap<String, Object> headers,
OutputStream outputStream) throws IOException {
if (feedOrEntry instanceof Feed) {
Feed feed = (Feed)feedOrEntry;
Document<Feed> doc = feed.getDocument();
doc.writeTo(outputStream);
} else {
Entry entry = (Entry)feedOrEntry;
Document<Entry> doc = entry.getDocument();
doc.writeTo(outputStream);
}
}
public boolean isReadable(Class<?> type) {
return (Feed.class.isAssignableFrom(type) || Entry.class.isAssignableFrom(type));
}
public Object readFrom(Class<Object> feedOrEntry, MediaType mediaType,
MultivaluedMap<String, String> headers,
InputStream inputStream) throws IOException {
Document<Element> doc = getAbdera().getParser().parse(inputStream);
Element el = doc.getRoot();
if (feedOrEntry.isAssignableFrom(el.getClass())) {
return el;
} else {
throw new IOException("Unexpected payload, expected "+feedOrEntry.getName()+
", received "+el.getClass().getName());
}
}
}
Notice I actually implemented Abdera is shaping up to be a nice API for working with Atom documents. Hopefully the above demonstrates how easy it is to integrate support for new formats into Jersey. »
Related Topics >>
Web Services and XML Comments
Comments are listed in date ascending order (oldest first)
Submitted by beuchelt on Wed, 2008-08-13 08:35.
I posted a complementing article on using the Jersey client API with Abdera here:
http://blog.beuchelt.org/2008/07/18/Using+Abdera+And+The+Jersey+Client+A...
Submitted by vzafzal on Wed, 2008-02-06 04:16.
Hi, thanks for the tutorial, it really is great!.
But I get this error when trying to run the above code:
A message body writer for Java type, class org.apache.abdera.parser.stax.FOMFeed, and MIME media type, application/atom+xml, was not found
Any idea what might be causing it?
Submitted by mhadley on Wed, 2008-02-06 06:53.
If you are using Jersey trunk code you shouldn't need to do anything else, Jersey will locate the reader/writer using the @Provider annotation. I'm guessing you are using the 0.5 snapshot which requires an additional step I forgot to mention. In that case you need to create two files in META-INF/services: javax.ws.rs.ext.MessageBodyReader and javax.ws.rs.ext.MessageBodyWriter. Add a single line to each file: "whatever.package.name.you.use.AbderaSupport". The EntityProvider sample that is included with the Jersey release shows how to register custom message body readers and writers in more detail. Sorry about that.
Submitted by sandoz on Thu, 2008-02-07 04:10.
Very Nice! I have extended Marc's example to support both JSON and XML, see here
|
||
|
|