Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing Default JSON Time Format with RESTEasy 3.x

I am using RESTEasy to implement a REST Service using JSON serialization. Currently, Dates are getting serialized to milliseconds since 1970. To improve compatibility, I would like to get my dates into one of two formats; milliseconds + timezone offset or ISO 8061.

It seems that RESTEasy used to use Jettison for JSON serialization, but from what I've been reading they've switch to Jackson ... all of this has made googling for help pretty hit or miss.

From what I can tell, I need to implement a ContextResolver along the lines of:

    public class JacksonConfig impelments ContextResolver<ObjectMapper>
    {
        private final OBjectMapper objectMapper;

        public JacksonConfig() throws Exception
        {
            objectMapper = new ObjectMapper.configure(
                               SerializationFeature.WRITE_DATE_AS_TIMESTAMPS, false);
        }

        @Override
        public ObjectMapper getContext(Class<?> arg0)
        {
            return objectMapper;
        }
     }

The thing I haven't been able to find, is what do I do with this? Where do I put it?

So the larger questions are, am I heading in the right direction and are my assumptions correct?

like image 741
insaneshow Avatar asked Oct 07 '13 15:10

insaneshow


People also ask

What is JSON time format?

JSON does not have a built-in type for date/time values. The general consensus is to store the date/time value as a string in ISO 8601 format. Example { "myDateTime": "2018-12-10T13:45:00.000Z" }

How do I change the date format in object mapper?

We can format a date using the setDateFormat() of ObjectMapper class. This method can be used for configuring the default DateFormat when serializing time values as Strings and deserializing from JSON Strings.

How does Jackson deserialize dates from JSON?

This is how i'm deserializing the date: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); getObjectMapper(). getDeserializationConfig(). setDateFormat(dateFormat);

How does Jackson serialize date?

It's important to note that Jackson will serialize the Date to a timestamp format by default (number of milliseconds since January 1st, 1970, UTC).


2 Answers

You need to register your ContextResolver implementation with Resteasy. You can do this by annotating your class with the @Provider annotation and allowing Resteasy to automatically scan it during startup, registering it in web.xml, or registering it in a class that extends javax.ws.rs.core.Application (if that is how you are bootstrapping Resteasy).

Registering via Annotations

@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper>
{
    private final ObjectMapper objectMapper;

    public JacksonConfig() throws Exception
    {
        objectMapper = new ObjectMapper.configure(
                           SerializationFeature.WRITE_DATE_AS_TIMESTAMPS, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> arg0)
    {
        return objectMapper;
    }
 }

Verify that classpath scanning is enabled in your web.xml file like so:

<context-param>
    <param-name>resteasy.scan</param-name>
    <param-value>true</param-value>
</context-param>

NOTE: If you are deploying this in JBoss 7 do not set the resteasy.scan context parameter as it is enabled by default.

Registering via web.xml

Add the following context parameter to your web.xml file. The value of the parameter should be the fully qualified class name of your ContextResolver.

<context-param>
      <param-name>resteasy.providers</param-name>
      <param-value>foo.contextresolver.JacksonConfig</paramvalue>
</context-param> 

Registering via Application

If you are using an Application class to configure Resteasy you can add your provider to the set of services and providers to register with Resteasy like so:

public class MyApp extends Application 
{
    @Override
    public Set<Class<?>> getClasses() 
    {
        HashSet<Class<?>> set = new HashSet<Class<?>>(2);
        set.add(JacksonConfig.class);
        set.add(MyService.class);
        return set;
    }
}

More on standalone configuration HERE

like image 162
gregwhitaker Avatar answered Sep 30 '22 05:09

gregwhitaker


Just annotate your fields with (note the string literal could be externalized/referred from a constant):

@javax.json.bind.annotation.JsonbDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
Date myDate;
like image 32
Radoslav Ivanov Avatar answered Sep 30 '22 07:09

Radoslav Ivanov