On Mon, Aug 20, 2012 at 6:44 PM, Matthew Pease <
mpe...@gmail.com> wrote:
> Any tips on using ObjectifyJacksonModule with RestEasy? OK... I guess
> this is getting a little off topic.
>
> But maybe someone out there has done this?
>
> Problem is that ObjectifyJacksonModule is based on Jackson 2.0 and the
> ObjectMapper you can obtain from ResteasyJacksonProvider is a Jackson 1.9
> sort of ObjectMapper.
>
> The result is that the registerModule() method doesn't like
> ObjectifyJacksonModule.
Yeah, don't use the ResteasyJacksonProvider. Derive your own
JacksonJsonProvider and use that. I'm not totally sure how you
configure it if you aren't using Guice, probably you just register it
as a normal provider.
Here's what ours looks like, but it has a lot of extra stuff to make
@JsonView work on jaxrs methods. You can ignore that. Really the
only important line is setMapper() in the constructor; pass in your
own ObjectMapper instance:
package st.voo.tick.util.json;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import unsuck.lang.ReflectionUtils;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
/**
* Overrides the normal jackson json provider's objectmapper with the
voost-specific one.
* This makes jaxrs calls serialize as we want. Note that we don't
bother using Resteasy's
* jackson integration, which loads itself outside of Guice and
becomes unavailable to us.
*
* We actually use resteasy's produces/consumes instructions here though.
*/
@Singleton
@Provider
@Consumes({"application/*+json", "text/json"})
@Produces({"application/*+json", "text/json"})
//@Slf4j
public class VoostJacksonProvider extends JacksonJsonProvider {
/** Never used, just to obtain the annotation reference */
private static class Fodder {
@SuppressWarnings("unused")
@JsonView(Object.class)
public int hasJsonView;
}
/** */
private static JsonView JSON_VIEW_ANNO =
ReflectionUtils.getField(Fodder.class,
"hasJsonView").getAnnotation(JsonView.class);
private static Annotation[] JSON_VIEW_ONLY = new Annotation[] {
JSON_VIEW_ANNO };
/** */
@Inject
public VoostJacksonProvider() {
this.setMapper(VoostObjectMapper.INSTANCE);
}
/** Unfortunately we need to add @JsonView(Object.class) to any call
that doesn't already have @JsonView */
@Override
public void writeTo(Object value, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,
Object> httpHeaders, OutputStream entityStream) throws IOException {
if (annotations == null) {
annotations = JSON_VIEW_ONLY;
} else if (!hasJsonView(annotations)) {
Annotation[] added = new Annotation[annotations.length + 1];
for (int i=0; i<annotations.length; i++)
added[i] = annotations[i];
added[annotations.length] = JSON_VIEW_ANNO;
annotations = added;
}
super.writeTo(value, type, genericType, annotations, mediaType,
httpHeaders, entityStream);
}
private boolean hasJsonView(Annotation[] annotations) {
for (Annotation anno: annotations)
if (anno instanceof JsonView)
return true;
return false;
}
}