kavai77
kavai77

Reputation: 6616

GlassFish JAX-RS Jackson custom JSON serialization

I have a JAX-RS resource and I'd like to use a custom JSON serializer for java.util.Calendar attribute using the @JsonSerialize(using=MySerializer.class).

import java.util.Calendar;
import org.codehaus.jackson.map.annotate.JsonSerialize;

public class FooBar {

    @JsonSerialize(using=MySerializer.class)
    private Calendar calendar;

    public FooBar() {
        calendar = Calendar.getInstance();
    }

    public Calendar getCalendar() {
        return calendar;
    }
}

MySerializer.java:

import java.io.IOException;
import java.util.Calendar;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

public class MySerializer
    extends JsonSerializer<Calendar>
{

    @Override
    public void serialize(Calendar c, JsonGenerator jg, SerializerProvider sp)
        throws IOException, JsonProcessingException
    {            
        jg.writeString("fooBar Calendar time: " + c.getTime());
    }

}

I made a simple project in NetBeans 7.1 and it works well.

When I use it in an other project with different deployment (EAR with multiple WARs and EJB JARs) then I receive

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class
com.example.FooBar and MIME media type application/json was not found

But if I put into the web.xml the init-parameter

<init-param>
   <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
   <param-value>true</param-value>
</init-param>

json serialization works, but the @JsonSerialize annotation does not work.

On the other hand the Netbeans project does't need POJOMappingFeature.

What could be the difference between these two applications?

What makes a difference where one application needs POJOMappingFeature and the other one don't?

Upvotes: 5

Views: 5505

Answers (2)

kavai77
kavai77

Reputation: 6616

Regarding the @JsonSerialize failure: If you have a getter of a field, you need to annotate the getter method with @JsonSerialize and not the field itself! It seems the getter method has a preference over the field on serialization. So the working code is:

import java.util.Calendar;
import org.codehaus.jackson.map.annotate.JsonSerialize;

public class FooBar {

    private Calendar calendar;

    public FooBar() {
        calendar = Calendar.getInstance();
    }

    @JsonSerialize(using=MySerializer.class)
    public Calendar getCalendar() {
        return calendar;
    }
}

Upvotes: 4

kavai77
kavai77

Reputation: 6616

Finally I found out the difference.

If I put jackson-jaxrs.jar into the WEB-INF/lib of WAR, then no POJOMappingFeature is required in web.xml, it can automatically serialize POJOs.

If you don't have this jar, then you need the following entry in web.xml:

<servlet>
    <servlet-name>ServletAdaptor</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>    
    <init-param>
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
      <param-value>true</param-value>
    </init-param>
    ...
</servlet>

Upvotes: 1

Related Questions