1

i implement an restful webservice with jersey 2.0 (jax-rs 2.0) and jackson on a glassfish 4 (i also try it in tomcat 8 with the same result). I have an dto with an date propertie, which i want send to the webservice.

For serialization and deserialization i have my own (De)Serializer. In junit test i send the bean to the webservice and the webservice send the same bean back.

So In the request i see that the date is formated like yyyy-MM-dd'T'HH:mm:ss.SSSZ, but in the response the date is like an unixtimestamp and my Deserializer throws an Exception java.text.ParseException: Unparseable date: "1378980107682"

Why my Server don't use my (De)Serializer classes?

The Request:

1 > Content-Type: application/json
{"name":"name1","lastname":"lastname2","date":"2013-09-12T13:26:30.752+0200"}

The Response:

2 < X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7) {"name":"name1","lastname":"lastname2","date":1378985190752}

My bean

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@JsonAutoDetect
@JsonIgnoreProperties (ignoreUnknown = true)
@JsonInclude (Include.NON_NULL)
public class User {

    private String name;
    private String lastname;
    private Date date;

    @JsonSerialize (using = MyDateSerializer.class)
    public Date getDate() {
        return date;
    }

    @JsonDeserialize (using = MyDateDeserializer.class)
    public void setDate(Date date) {
        this.date = date;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
}

My Serializer

public class MyDateSerializer extends JsonSerializer<Date> {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

    @Override
    public void serialize(Date aDate, JsonGenerator aJsonGenerator, SerializerProvider aSerializerProvider)
            throws IOException, JsonProcessingException {
        System.out.println("MyDateSerializer.serialize()");

        String dateString = dateFormat.format(aDate);
        System.out.println("dateString [" + dateString + "]");
        aJsonGenerator.writeString(dateString);
    }
}

My Deserializer

public class MyDateDeserializer extends JsonDeserializer<Date> {

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

    @Override
    public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        System.out.println("MyDateDeserializer.deserialize()");

        String date = jsonParser.getText();
        System.out.println("MyDateDeserializer.getText [" + date + "]");
        try {
            return format.parse(date);
        } catch (ParseException e) {            
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

My Application

public class MyRESTExampleApplication extends ResourceConfig {

    public MyRESTExampleApplication() {
        packages("com.carano.fleet4all.restExample");
        register(JacksonConfigurator.class);
        register(JacksonFeature.class);
    }
}

My web.xml

<display-name>restExample</display-name>
  <servlet>
    <display-name>JAX-RS REST Servlet</display-name>
    <servlet-name>REST-Servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.carano.fleet4all.restExample.MyRESTExampleApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>REST-Servlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
Tim
  • 643
  • 3
  • 12
  • 23

1 Answers1

2

One possibility is that you are using wrong set of annotations, with respect to Jackson version in use. Jackson 1.x and 2.x live in different Java packages (1.x under "org.codehaus.jackson", 2.x under "com.fasterxml.jackson"); and annotations and ObjectMapper have to match. This would be the case if (de)serializer is not getting called.

But are you sure you need a custom serializer, deserializer? Why not configure ObjectMapper with your DateFormat and let it do this?

You can also configure whether Jackson is to use Java timestamp (milliseconds since 1.1.1970) or textual format; I don't remember which one is default.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
  • 1
    I found that my ObjectMapper `JacksonConfigurator implements ContextResolver` is from package `org.codehaus.jackson`. But didn't find an jar from `com.fasterxml.jackson` with the `ObjectMapper` inside. – Tim Sep 16 '13 at 07:06
  • Right, that is another possible 1.x vs 2.x mismatch -- JAX-RS provider used also has to be compatible. – StaxMan Sep 17 '13 at 03:32
  • The problem is also that the gf4 supports both versions of jackson. So i don't get an ClassNotFoundException. I wrote my own `JacksonFeature` Class that register the fasterxml `JacksonJaxbJsonProvider` and so i can use the fasterxml jackson library with gf4. My JacksonFeature disable also the MOXy Provider. – Tim Sep 18 '13 at 06:29