If you're working with Java and JSON, the Jackson library is likely part of your tech stack. One of the most powerful yet underused annotations it provides is @JsonFormat.
In this ultimate guide, we’ll break down what @JsonFormat does, when to use it, and how to handle advanced scenarios with fully working examples. This post is optimized for SEO to help developers find quick and accurate answers.
✅ What is @JsonFormat in Jackson?
@JsonFormat is a Jackson annotation that helps control how Java fields are serialized (Java to JSON) or deserialized (JSON to Java). This is especially useful for dates, enums, and number formats.
Import Statement:
import com.fasterxml.jackson.annotation.JsonFormat;
Dependencies
Make sure you include the correct Jackson modules for java.time:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.15.3</version>
</dependency>
And register it:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule());
📅 1. Formatting Dates and Times
Basic Example with Date
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;
public class Event {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Kolkata")
private Date eventDate;
public Event(Date eventDate) {
this.eventDate = eventDate;
}
public Date getEventDate() {
return eventDate;
}
public static void main(String[] args) throws Exception {
Event event = new Event(new Date());
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(event);
System.out.println(json);
}
}
JSON Output:
{ "eventDate": "2025-07-19 15:00:00" }
Working with LocalDateTime
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.LocalDateTime;
public class Schedule {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime start;
public Schedule(LocalDateTime start) {
this.start = start;
}
public static void main(String[] args) throws Exception {
Schedule schedule = new Schedule(LocalDateTime.now());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
System.out.println(mapper.writeValueAsString(schedule));
}
}
Output:
{ "start": "2025-07-19T12:30:00" }
2. Customizing Enum Serialization
Enum as Full Object
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
public class User {
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
private Status status;
public User(Status status) {
this.status = status;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
User user = new User(Status.ACTIVE);
System.out.println(mapper.writeValueAsString(user));
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
enum Status {
ACTIVE("Active"), INACTIVE("Inactive");
private final String label;
Status(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
}
Sample Output:
{"status":{"label":"Active"}}
🔢 3. Formatting Numbers
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.ObjectMapper; import java.math.BigDecimal; public class Invoice { @JsonFormat(shape = JsonFormat.Shape.STRING) private BigDecimal amount; public Invoice(BigDecimal amount) { this.amount = amount; } public static void main(String[] args) throws Exception { Invoice invoice = new Invoice(new BigDecimal("12345.67")); ObjectMapper mapper = new ObjectMapper(); System.out.println(mapper.writeValueAsString(invoice)); } }
Sample output:
{"amount":"12345.67"}
📦 4. Shape Control: Arrays vs Objects
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.ObjectMapper; public class BoxExample { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); Box box = new Box(new Point(10, 20), new Point(30, 40)); System.out.println(mapper.writeValueAsString(box)); } static class Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } static class Box { @JsonFormat(shape = JsonFormat.Shape.ARRAY) public Point topLeft; @JsonFormat(shape = JsonFormat.Shape.ARRAY) public Point bottomRight; public Box(Point topLeft, Point bottomRight) { this.topLeft = topLeft; this.bottomRight = bottomRight; } } }
Sample output
{"topLeft":[10,20],"bottomRight":[30,40]}
🧪 5. Case-Insensitive Enum Deserialization
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.MapperFeature; public class CaseInsensitiveEnumExample { enum Role { ADMIN, USER, GUEST } public static void main(String[] args) throws Exception { String json = "\"AdMiN\""; ObjectMapper mapper = new ObjectMapper(); mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); Role role = mapper.readValue(json, Role.class); System.out.println(role); // Output: ADMIN } }
Sample output
ADMIN
🛑 6. Common Pitfalls
- Pattern must match the input exactly during deserialization.
- Using the wrong timezone may cause incorrect results.
- Not all types support all Shape options (e.g., BigDecimal cannot be OBJECT).
🧰 7 Tips
Prefer LocalDate, LocalDateTime, ZonedDateTime from java.time over java.util.Date.
You can also use global config via ObjectMapper:
ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
ليست هناك تعليقات:
إرسال تعليق
Please do not add any spam links in the comments section.