I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this article, we try to understand how to use @JsonFormat in Jackson. It is a Jackson annotation that is used to specify how to format fields and/or properties for JSON output. Specifically, this annotation allows you to specify how to format

Specifically, this annotation allows you to specify how to format Date and Calendar values according to a SimpleDateFormat format.

2. Maven Dependency

@JsonFormat is defined in the jackson-databind package so we need the following Maven Dependency:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.4</version>
</dependency>

3. Getting Started

3.1. Using the Default Format

To get started, we will demonstrate the concepts of using the @JsonFormat annotation with a class representing a user.

Since we are trying to explain the details of the annotation, the User object will be created on request (and not stored or loaded from a database) and serialized to JSON:

public class User {
    private String firstName;
    private String lastName;
    private Date createdDate = new Date();

    // standard constructor, setters and getters
}

Building and running this code example returns the following output:

{"firstName":"John","lastName":"Smith","createdDate":1482047026009}

As you can see, the createdDate field is shown as the number of seconds since epoch which is the default format used for Date fields.

3.2. Using the Annotation on a Getter

Let us now use @JsonFormat to specify the format that the createdDate field should be serialized. Here is the User class updated for this change. The createdDate field has been annotated as shown to specify the date format.

The data format used for the pattern argument is specified by SimpleDateFormat:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "[email protected]:mm:ss.SSSZ")
private Date createdDate;

With this change in place, we build the project again and run it. The output is shown below:

{"firstName":"John","lastName":"Smith","createdDate":"[email protected]:53:34.740+0000"}

As you can see, the createdDate field has been formatted using the specified SimpleDateFormat format using the @JsonFormat annotation.

The above example demonstrates using the annotation on a field. It can also be used in a getter method (a property) as follows.

For instance, you may have a property which is being computed on invocation. You can use the annotation on the getter method in such a case. Note that the pattern has also been changed to return just the date part of the instant:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
public Date getCurrentDate() {
    return new Date();
}

The resultant output is as follows:

{ ... , "currentDate":"2016-12-18", ...}

3.3. Specifying the Locale

In addition to specifying the date format, you can also specify the locale to be used for serialization. Not specifying this parameter results in serialization being performed with the default locale:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "[email protected]:mm:ss.SSSZ", locale = "en_GB")
public Date getCurrentDate() {
    return new Date();
}

3.4. Specifying the Shape

Using @JsonFormat with shape set to JsonFormat.Shape.NUMBER results in the default output for Date types — as the number of seconds since the epoch. The parameter pattern is not applicable to this case and is ignored:

@JsonFormat(shape = JsonFormat.Shape.NUMBER)
public Date getDateNum() {
    return new Date();
}

The output is as shown below:

{ ..., "dateNum":1482054723876 }

4. Conclusion

In conclusion, @JsonFormat is used to control the output format of Date and Calendar types as demonstrated above.

The sample code shown above is available over on GitHub.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS

  Subscribe  
newest oldest most voted
Notify of
Sakthi
Guest

how do we use this @JsonFormat, if my object is generated from XSD using JAXB ?

Eugen Paraschiv
Guest

Well Sakthi, it’s only if you’re using Jackson and more importantly JSON that you’re going to be able to use this annotation.
Hope that helps. Cheers,
Eugen.

Sakthi
Guest

Thanks for the reply, yes we are using Jackson to convert our Java Object into JSON format, but the java object are getting generated by JAXB. if i have to leverage this @Jsonformat for formatting a date field with in a Java object , how can i do it ? thanks again.

Grzegorz Piwowarek
Guest

In this case, you need to look for a solution in JAXB because it is responsible for generating classes and putting annotations on it. Jaxb’s Annotate plugin should be able to help here: https://github.com/highsource/jaxb2-annotate-plugin

shivang goswami
Guest

hi,
i m using @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = “yyyy-MM-dd”) with an instance field but its not working. I still see response in seconds

Grzegorz Piwowarek
Guest

We would be happy to help if you could make a pull request to our codebase with a failing test that reproduces that problem, other than this, it’s really hard to guess the reason. Are you using Jackson?

shivang goswami
Guest

Thanks for d reply..!!
Yes am using Jackson 2.3.0. Am i using the correct version ?

shivang goswami
Guest

hi Grzegorz,
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern =”yyyy-MM-dd”) is working now but it converts to an incorrect date string. The actual date that m fetching from Database is 4/20/2017 12:00:00 AM which gets converted to 2017-04-19 06:30:00 in the response.

Grzegorz Piwowarek
Guest

That’s getting interesting 🙂 Are you 100% sure that this is the exact date that gets transformer to this? can you prepare an isolated test case? this annotation is non-invasive

shivang goswami
Guest

Thanks for your interest..!! 🙂 Using the timezone in the annotation fixed it. I wasn’t aware that by default jackson uses GMT timezone. Using this did the trick –> @JsonFormat(shape = JsonFormat.Shape.ANY, pattern=”yyyy-MM-dd”, timezone = “IST”). I wonder if ders a way to use system timezone for internationalization. Cheers..!!

Johx Merxhus
Guest

Hi!!
I want to support several patterns something like this :
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = {“yyyy-MM-dd”, “yyyy-MM-dd HH:mm”})
Is it possible for JsonFormat? maybe Do you have some alternative?

Please, thanks.

Grzegorz Piwowarek
Guest

Just put your date formats in a comma-separated single string and this should work.
Something like: pattern=”yyyy-MM-dd, yyyy-MM-dd HH:mm”

Let me know if this helps.
Grzegorz

Johx Merxhus
Guest

Thanks, but I got this result :
Could not read document: Can not deserialize value of type java.util.Date from String “2017-05-31”: expected format “yyyy-MM-dd HH:mm, yyyy-MM-dd”n at [Source: [email protected]; line: 7, column: 17] (through reference chain: “taskDefinition”]->CronDefinition[“endTime”]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.util.Date from String “2017-05-31”: expected format “yyyy-MM-dd hh:mm, yyyy-MM-dd”n at [Source: [email protected]; line: 7, column: 17] (through reference chain:Task[“taskDefinition”]->CronDefinition[“endTime”]
Maybe Do you have some alternative? it is not working,
Thanks,

Grzegorz Piwowarek
Guest

Well, if you could prepare a test case reproducing this error, we would be glad to look. Otherwise, it’s super hard to say anything without seeing the code.

btw, you can always just write a custom serializer/deserializer.

Johx Merxhus
Guest

Okay, thank you very much!
Kind regards.