Core annotations used for value types, used by Jackson data binding package.
—
Control serialization format for dates, numbers, and other values with comprehensive formatting options.
Configure serialization format for values including dates, numbers, and collections.
/**
* Configure serialization format for values
* @param pattern Format pattern (e.g., date pattern, number pattern)
* @param shape Serialization shape/structure
* @param locale Locale for formatting (default: "##default")
* @param timezone Timezone for date formatting (default: "##default")
* @param lenient Whether to use lenient parsing
* @param with Format features to enable
* @param without Format features to disable
*/
@JsonFormat(String pattern = "",
JsonFormat.Shape shape = JsonFormat.Shape.ANY,
String locale = JsonFormat.DEFAULT_LOCALE,
String timezone = JsonFormat.DEFAULT_TIMEZONE,
OptBoolean lenient = OptBoolean.DEFAULT,
JsonFormat.Feature[] with = {},
JsonFormat.Feature[] without = {})
public @interface JsonFormat {
enum Shape {
/** Use natural/default shape for the type */
ANY,
/** Use natural shape (object for objects, array for arrays) */
NATURAL,
/** Force scalar representation */
SCALAR,
/** Force array representation */
ARRAY,
/** Force object representation */
OBJECT,
/** Force numeric representation */
NUMBER,
/** Force floating-point number */
NUMBER_FLOAT,
/** Force integer number */
NUMBER_INT,
/** Force string representation */
STRING,
/** Force boolean representation */
BOOLEAN,
/** Force binary representation */
BINARY;
public boolean isNumeric();
public boolean isStructured();
}
enum Feature {
/** Accept single value as single-element array */
ACCEPT_SINGLE_VALUE_AS_ARRAY,
/** Accept case-insensitive property names */
ACCEPT_CASE_INSENSITIVE_PROPERTIES,
/** Read unknown enum values as null */
READ_UNKNOWN_ENUM_VALUES_AS_NULL,
/** Read unknown enum values using @JsonEnumDefaultValue */
READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE,
/** Read date timestamps as nanoseconds instead of milliseconds */
READ_DATE_TIMESTAMPS_AS_NANOSECONDS,
/** Accept case-insensitive enum values */
ACCEPT_CASE_INSENSITIVE_VALUES,
/** Write date timestamps as nanoseconds */
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,
/** Write dates with zone ID information */
WRITE_DATES_WITH_ZONE_ID,
/** Write single-element arrays without array wrapper */
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,
/** Write Map entries in sorted order */
WRITE_SORTED_MAP_ENTRIES,
/** Adjust dates to context timezone */
ADJUST_DATES_TO_CONTEXT_TIME_ZONE
}
/** Default locale marker */
String DEFAULT_LOCALE = "##default";
/** Default timezone marker */
String DEFAULT_TIMEZONE = "##default";
}Usage Examples:
public class Event {
private String name;
// Date formatting with pattern
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime eventTime;
// Date as timestamp (milliseconds)
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
private LocalDateTime createdAt;
// Date as string with timezone
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC")
private ZonedDateTime scheduledTime;
// Number formatting
@JsonFormat(pattern = "#,##0.00")
private BigDecimal price;
// Array as single value when only one element
@JsonFormat(with = JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)
private List<String> tags;
}
// Results:
// "eventTime": "2024-01-15 14:30:00"
// "createdAt": 1705328200000
// "scheduledTime": "2024-01-15T14:30:00.000Z"
// "price": "1,234.56"
// "tags": "single-tag" (instead of ["single-tag"])public enum Priority {
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
LOW(1),
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
MEDIUM(2),
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
HIGH(3);
private final int value;
Priority(int value) {
this.value = value;
}
@JsonValue
public int getValue() {
return value;
}
}
// Serializes as: 1, 2, 3 instead of "LOW", "MEDIUM", "HIGH"public class DataContainer {
// Sort map entries during serialization
@JsonFormat(with = JsonFormat.Feature.WRITE_SORTED_MAP_ENTRIES)
private Map<String, Object> properties;
// Accept single value as array
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<String> items;
// Custom array formatting
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
private String[] coordinates; // Force object representation instead of array
}
// properties will be serialized with keys in alphabetical order
// items can deserialize both ["value"] and "value" as single-element array
// coordinates might serialize as {"0": "x", "1": "y"} instead of ["x", "y"]public class LocalizedData {
@JsonFormat(pattern = "dd/MM/yyyy", locale = "en_GB")
private LocalDate ukDate;
@JsonFormat(pattern = "MM/dd/yyyy", locale = "en_US")
private LocalDate usDate;
@JsonFormat(pattern = "#,##0.00", locale = "de_DE")
private BigDecimal germanNumber; // Uses comma as decimal separator
@JsonFormat(pattern = "#,##0.00", locale = "en_US")
private BigDecimal usNumber; // Uses period as decimal separator
}public class TimeZoneExample {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
private LocalDateTime utcTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "America/New_York")
private LocalDateTime nyTime;
@JsonFormat(with = JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
private ZonedDateTime contextTime; // Adjusts to ObjectMapper's timezone
@JsonFormat(with = JsonFormat.Feature.WRITE_DATES_WITH_ZONE_ID)
private ZonedDateTime zoneDateTime; // Includes zone ID in output
}public class ShapeExamples {
// Force string representation of number
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long bigId; // "123456789012345" instead of 123456789012345
// Force array representation of single value
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private String singleValue; // ["value"] instead of "value"
// Force object representation of primitive
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
private boolean flag; // {"value": true} instead of true
}public class FeatureCombinations {
@JsonFormat(
pattern = "yyyy-MM-dd",
with = {
JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE,
JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES
},
without = {
JsonFormat.Feature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS
}
)
private LocalDate configuredDate;
@JsonFormat(
with = {
JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,
JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY
}
)
private List<String> flexibleArray;
}Mark enum field as default value for unknown enum values during deserialization.
/**
* Mark enum value as default for unknown enum values
* Only effective when READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE is enabled
*/
@JsonEnumDefaultValue
public @interface JsonEnumDefaultValue;Usage Examples:
public enum Status {
ACTIVE,
INACTIVE,
PENDING,
@JsonEnumDefaultValue
UNKNOWN; // Used when deserializing unrecognized values
}
public class Order {
private Status status;
// When JSON contains {"status": "CANCELLED"} (unknown value)
// It will deserialize as Status.UNKNOWN if feature is enabled
}Configuration classes for programmatic format control.
/**
* Value class for JsonFormat configuration
*/
public static class JsonFormat.Value implements JacksonAnnotationValue<JsonFormat> {
public static final JsonFormat.Value EMPTY;
public static JsonFormat.Value forPattern(String pattern);
public static JsonFormat.Value forShape(JsonFormat.Shape shape);
public static JsonFormat.Value forLeniency(Boolean lenient);
public String getPattern();
public JsonFormat.Shape getShape();
public Locale getLocale();
public TimeZone getTimeZone();
public Boolean getLenient();
public JsonFormat.Features getFeatures();
public JsonFormat.Value withPattern(String pattern);
public JsonFormat.Value withShape(JsonFormat.Shape shape);
public JsonFormat.Value withLocale(Locale locale);
public JsonFormat.Value withTimeZone(TimeZone tz);
public JsonFormat.Value withLenient(Boolean lenient);
public JsonFormat.Value withFeature(JsonFormat.Feature feature);
public JsonFormat.Value withoutFeature(JsonFormat.Feature feature);
}
/**
* Helper class for managing format features
*/
public static class JsonFormat.Features {
public static final JsonFormat.Features EMPTY;
public static JsonFormat.Features construct(JsonFormat.Feature[] enabled,
JsonFormat.Feature[] disabled);
public JsonFormat.Features with(JsonFormat.Feature... features);
public JsonFormat.Features without(JsonFormat.Feature... features);
public boolean get(JsonFormat.Feature feature);
}public class ConditionalFormatting {
// Different format based on value
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long getId() {
// Custom getter that formats differently based on conditions
return id != null && id > 1000000L ? id : null;
}
// Lenient parsing for user input
@JsonFormat(lenient = OptBoolean.TRUE)
private LocalDate userInputDate; // More forgiving date parsing
// Strict formatting for API output
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", lenient = OptBoolean.FALSE)
private LocalDateTime apiTimestamp;
}Install with Tessl CLI
npx tessl i tessl/maven-com-fasterxml-jackson-core--jackson-annotations