0
# Annotations
1
2
Jackson Databind provides extensive annotation support for controlling serialization and deserialization behavior. These annotations allow fine-grained control over property naming, visibility, formatting, validation, and custom processing without modifying the underlying Java classes.
3
4
## Core Serialization/Deserialization Annotations
5
6
### @JsonSerialize
7
8
Controls serialization aspects of properties and classes.
9
10
```java { .api }
11
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
12
@Retention(RetentionPolicy.RUNTIME)
13
@JacksonAnnotation
14
public @interface JsonSerialize {
15
// Custom serializer
16
Class<? extends JsonSerializer> using() default JsonSerializer.None.class;
17
Class<? extends JsonSerializer> contentUsing() default JsonSerializer.None.class;
18
Class<? extends JsonSerializer> keyUsing() default JsonSerializer.None.class;
19
Class<? extends JsonSerializer> nullsUsing() default JsonSerializer.None.class;
20
21
// Type specification
22
Class<?> as() default Void.class;
23
Class<?> keyAs() default Void.class;
24
Class<?> contentAs() default Void.class;
25
26
// Inclusion control
27
JsonSerialize.Inclusion include() default JsonSerialize.Inclusion.DEFAULT_INCLUSION;
28
29
// Static/dynamic typing
30
JsonSerialize.Typing typing() default JsonSerialize.Typing.DEFAULT_TYPING;
31
32
// Converter
33
Class<? extends Converter> converter() default Converter.None.class;
34
Class<? extends Converter> contentConverter() default Converter.None.class;
35
36
// Nested enums
37
public enum Inclusion {
38
ALWAYS,
39
NON_NULL,
40
NON_ABSENT,
41
NON_EMPTY,
42
NON_DEFAULT,
43
CUSTOM,
44
USE_DEFAULTS;
45
}
46
47
public enum Typing {
48
DYNAMIC,
49
STATIC,
50
DEFAULT_TYPING;
51
}
52
}
53
```
54
55
### @JsonDeserialize
56
57
Controls deserialization aspects of properties and classes.
58
59
```java { .api }
60
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
61
@Retention(RetentionPolicy.RUNTIME)
62
@JacksonAnnotation
63
public @interface JsonDeserialize {
64
// Custom deserializer
65
Class<? extends JsonDeserializer> using() default JsonDeserializer.None.class;
66
Class<? extends JsonDeserializer> contentUsing() default JsonDeserializer.None.class;
67
Class<? extends KeyDeserializer> keyUsing() default KeyDeserializer.None.class;
68
69
// Builder support
70
Class<?> builder() default Void.class;
71
72
// Type specification
73
Class<?> as() default Void.class;
74
Class<?> keyAs() default Void.class;
75
Class<?> contentAs() default Void.class;
76
77
// Converter
78
Class<? extends Converter> converter() default Converter.None.class;
79
Class<? extends Converter> contentConverter() default Converter.None.class;
80
}
81
```
82
83
### @JsonProperty
84
85
Controls property-level serialization and deserialization.
86
87
```java { .api }
88
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
89
@Retention(RetentionPolicy.RUNTIME)
90
@JacksonAnnotation
91
public @interface JsonProperty {
92
// Property name (default is auto-detected)
93
String value() default USE_DEFAULT_NAME;
94
95
// Namespace (for XML, etc.)
96
String namespace() default "";
97
98
// Required property
99
boolean required() default false;
100
101
// Property index (for order)
102
int index() default INDEX_UNKNOWN;
103
104
// Default value as string
105
String defaultValue() default "";
106
107
// Access control
108
JsonProperty.Access access() default JsonProperty.Access.AUTO;
109
110
// Constants
111
String USE_DEFAULT_NAME = "";
112
int INDEX_UNKNOWN = -1;
113
114
// Access enum
115
public enum Access {
116
AUTO,
117
READ_ONLY,
118
WRITE_ONLY,
119
READ_WRITE;
120
}
121
}
122
```
123
124
### @JsonIgnore and @JsonIgnoreProperties
125
126
Control property visibility and ignoring.
127
128
```java { .api }
129
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
130
@Retention(RetentionPolicy.RUNTIME)
131
@JacksonAnnotation
132
public @interface JsonIgnore {
133
// Whether to ignore (default true)
134
boolean value() default true;
135
}
136
137
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
138
@Retention(RetentionPolicy.RUNTIME)
139
@JacksonAnnotation
140
public @interface JsonIgnoreProperties {
141
// Property names to ignore
142
String[] value() default {};
143
144
// Whether to ignore unknown properties
145
boolean ignoreUnknown() default false;
146
147
// Whether to allow getters for ignored setters
148
boolean allowGetters() default false;
149
150
// Whether to allow setters for ignored getters
151
boolean allowSetters() default false;
152
}
153
```
154
155
## Property Configuration Annotations
156
157
### @JsonInclude
158
159
Controls when properties are included in serialization.
160
161
```java { .api }
162
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
163
@Retention(RetentionPolicy.RUNTIME)
164
@JacksonAnnotation
165
public @interface JsonInclude {
166
// Inclusion strategy
167
JsonInclude.Include value() default JsonInclude.Include.ALWAYS;
168
169
// Content inclusion (for collections/maps)
170
JsonInclude.Include content() default JsonInclude.Include.ALWAYS;
171
172
// Custom value filter
173
Class<?> valueFilter() default Void.class;
174
Class<?> contentFilter() default Void.class;
175
176
// Include enum
177
public enum Include {
178
ALWAYS,
179
NON_NULL,
180
NON_ABSENT,
181
NON_EMPTY,
182
NON_DEFAULT,
183
CUSTOM,
184
USE_DEFAULTS;
185
}
186
}
187
```
188
189
### @JsonSetter
190
191
Controls deserialization settings for properties.
192
193
```java { .api }
194
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
195
@Retention(RetentionPolicy.RUNTIME)
196
@JacksonAnnotation
197
public @interface JsonSetter {
198
// Property name
199
String value() default "";
200
201
// Null handling
202
JsonSetter.Nulls nulls() default JsonSetter.Nulls.DEFAULT;
203
JsonSetter.Nulls contentNulls() default JsonSetter.Nulls.DEFAULT;
204
205
// Null handling enum
206
public enum Nulls {
207
DEFAULT,
208
SET,
209
SKIP,
210
FAIL,
211
AS_EMPTY;
212
}
213
}
214
```
215
216
### @JsonGetter and @JsonSetter methods
217
218
```java { .api }
219
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
220
@Retention(RetentionPolicy.RUNTIME)
221
@JacksonAnnotation
222
public @interface JsonGetter {
223
// Property name (default derived from method name)
224
String value() default "";
225
}
226
227
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
228
@Retention(RetentionPolicy.RUNTIME)
229
@JacksonAnnotation
230
public @interface JsonSetter {
231
// Property name (default derived from method name)
232
String value() default "";
233
234
// Null handling
235
JsonSetter.Nulls nulls() default JsonSetter.Nulls.DEFAULT;
236
JsonSetter.Nulls contentNulls() default JsonSetter.Nulls.DEFAULT;
237
}
238
```
239
240
## Format and Type Annotations
241
242
### @JsonFormat
243
244
Controls formatting of values during serialization/deserialization.
245
246
```java { .api }
247
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE})
248
@Retention(RetentionPolicy.RUNTIME)
249
@JacksonAnnotation
250
public @interface JsonFormat {
251
// Format pattern (dates, numbers, etc.)
252
String pattern() default "";
253
254
// Shape of serialized value
255
JsonFormat.Shape shape() default JsonFormat.Shape.ANY;
256
257
// Locale specification
258
String locale() default "##default";
259
260
// Timezone specification
261
String timezone() default "##default";
262
263
// Leniency for parsing
264
JsonFormat.OptBoolean lenient() default JsonFormat.OptBoolean.DEFAULT;
265
266
// Features for formatting
267
JsonFormat.Feature[] with() default {};
268
JsonFormat.Feature[] without() default {};
269
270
// Shape enum
271
public enum Shape {
272
ANY,
273
NATURAL,
274
SCALAR,
275
ARRAY,
276
OBJECT,
277
STRING,
278
NUMBER,
279
NUMBER_FLOAT,
280
NUMBER_INT,
281
BOOLEAN,
282
BINARY;
283
}
284
285
// Optional boolean enum
286
public enum OptBoolean {
287
TRUE, FALSE, DEFAULT;
288
}
289
290
// Format features
291
public enum Feature {
292
ACCEPT_SINGLE_VALUE_AS_ARRAY,
293
ACCEPT_CASE_INSENSITIVE_PROPERTIES,
294
ACCEPT_CASE_INSENSITIVE_VALUES,
295
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,
296
WRITE_DATES_WITH_ZONE_ID,
297
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,
298
ADJUST_DATES_TO_CONTEXT_TIME_ZONE;
299
}
300
}
301
```
302
303
### @JsonTypeInfo and Polymorphic Type Handling
304
305
```java { .api }
306
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
307
@Retention(RetentionPolicy.RUNTIME)
308
@JacksonAnnotation
309
public @interface JsonTypeInfo {
310
// How type information is included
311
JsonTypeInfo.Id use() default JsonTypeInfo.Id.CLASS;
312
313
// Where type information is included
314
JsonTypeInfo.As include() default JsonTypeInfo.As.PROPERTY;
315
316
// Property name for type information
317
String property() default "";
318
319
// Default implementation class
320
Class<?> defaultImpl() default JsonTypeInfo.None.class;
321
322
// Visibility of type property
323
boolean visible() default false;
324
325
// Type identification strategies
326
public enum Id {
327
NONE,
328
CLASS,
329
MINIMAL_CLASS,
330
NAME,
331
DEDUCTION,
332
CUSTOM;
333
}
334
335
// Type inclusion strategies
336
public enum As {
337
PROPERTY,
338
WRAPPER_OBJECT,
339
WRAPPER_ARRAY,
340
EXTERNAL_PROPERTY,
341
EXISTING_PROPERTY;
342
}
343
344
// Marker class
345
abstract class None { }
346
}
347
348
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
349
@Retention(RetentionPolicy.RUNTIME)
350
@JacksonAnnotation
351
public @interface JsonSubTypes {
352
// Subtype specifications
353
JsonSubTypes.Type[] value();
354
355
// Type specification
356
@Target({})
357
@Retention(RetentionPolicy.RUNTIME)
358
public @interface Type {
359
// Subtype class
360
Class<?> value();
361
362
// Type name/id
363
String name() default "";
364
365
// Alternative names
366
String[] names() default {};
367
}
368
}
369
370
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
371
@Retention(RetentionPolicy.RUNTIME)
372
@JacksonAnnotation
373
public @interface JsonTypeName {
374
// Type name for this class
375
String value() default "";
376
}
377
```
378
379
## Creator Annotations
380
381
### @JsonCreator
382
383
Marks constructors and factory methods for deserialization.
384
385
```java { .api }
386
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR})
387
@Retention(RetentionPolicy.RUNTIME)
388
@JacksonAnnotation
389
public @interface JsonCreator {
390
// Creation mode
391
JsonCreator.Mode mode() default JsonCreator.Mode.DEFAULT;
392
393
// Creation modes
394
public enum Mode {
395
DEFAULT,
396
DELEGATING,
397
PROPERTIES,
398
DISABLED;
399
}
400
}
401
```
402
403
### @JsonValue
404
405
Marks a method as providing the serialized value for an object.
406
407
```java { .api }
408
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
409
@Retention(RetentionPolicy.RUNTIME)
410
@JacksonAnnotation
411
public @interface JsonValue {
412
// Whether annotation is active
413
boolean value() default true;
414
}
415
```
416
417
## Advanced Annotations
418
419
### @JsonUnwrapped
420
421
Controls unwrapping of nested objects.
422
423
```java { .api }
424
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
425
@Retention(RetentionPolicy.RUNTIME)
426
@JacksonAnnotation
427
public @interface JsonUnwrapped {
428
// Whether to unwrap
429
boolean enabled() default true;
430
431
// Prefix for unwrapped properties
432
String prefix() default "";
433
434
// Suffix for unwrapped properties
435
String suffix() default "";
436
}
437
```
438
439
### @JsonAnySetter and @JsonAnyGetter
440
441
Handle dynamic properties that aren't known at compile time.
442
443
```java { .api }
444
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
445
@Retention(RetentionPolicy.RUNTIME)
446
@JacksonAnnotation
447
public @interface JsonAnySetter {
448
// Whether annotation is enabled
449
boolean enabled() default true;
450
}
451
452
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
453
@Retention(RetentionPolicy.RUNTIME)
454
@JacksonAnnotation
455
public @interface JsonAnyGetter {
456
// Whether annotation is enabled
457
boolean enabled() default true;
458
}
459
```
460
461
### @JsonManagedReference and @JsonBackReference
462
463
Handle bidirectional relationships to prevent infinite recursion.
464
465
```java { .api }
466
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD})
467
@Retention(RetentionPolicy.RUNTIME)
468
@JacksonAnnotation
469
public @interface JsonManagedReference {
470
// Reference name (for matching with back reference)
471
String value() default "defaultReference";
472
}
473
474
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD})
475
@Retention(RetentionPolicy.RUNTIME)
476
@JacksonAnnotation
477
public @interface JsonBackReference {
478
// Reference name (must match managed reference)
479
String value() default "defaultReference";
480
}
481
```
482
483
### @JsonIdentityInfo
484
485
Handles object identity to avoid duplication and cycles.
486
487
```java { .api }
488
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
489
@Retention(RetentionPolicy.RUNTIME)
490
@JacksonAnnotation
491
public @interface JsonIdentityInfo {
492
// ID generator class
493
Class<? extends ObjectIdGenerator> generator();
494
495
// Property name for ID
496
String property() default "@id";
497
498
// Whether to resolve references automatically
499
boolean resolver() default false;
500
501
// Custom resolver class
502
Class<? extends ObjectIdResolver> resolver() default ObjectIdResolver.class;
503
504
// Identity scope
505
Class<?> scope() default Object.class;
506
}
507
```
508
509
## Bean and Builder Annotations
510
511
### @JsonPOJOBuilder
512
513
Configures builder classes for deserialization.
514
515
```java { .api }
516
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
517
@Retention(RetentionPolicy.RUNTIME)
518
@JacksonAnnotation
519
public @interface JsonPOJOBuilder {
520
// Name of build method
521
String buildMethodName() default "build";
522
523
// Prefix for builder methods
524
String withPrefix() default "with";
525
}
526
```
527
528
### @JsonAutoDetect
529
530
Controls auto-detection of properties, getters, setters, etc.
531
532
```java { .api }
533
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
534
@Retention(RetentionPolicy.RUNTIME)
535
@JacksonAnnotation
536
public @interface JsonAutoDetect {
537
// Visibility settings
538
JsonAutoDetect.Visibility getterVisibility() default JsonAutoDetect.Visibility.DEFAULT;
539
JsonAutoDetect.Visibility isGetterVisibility() default JsonAutoDetect.Visibility.DEFAULT;
540
JsonAutoDetect.Visibility setterVisibility() default JsonAutoDetect.Visibility.DEFAULT;
541
JsonAutoDetect.Visibility creatorVisibility() default JsonAutoDetect.Visibility.DEFAULT;
542
JsonAutoDetect.Visibility fieldVisibility() default JsonAutoDetect.Visibility.DEFAULT;
543
544
// Visibility enum
545
public enum Visibility {
546
ANY,
547
NON_PRIVATE,
548
PROTECTED_AND_PUBLIC,
549
PUBLIC_ONLY,
550
NONE,
551
DEFAULT;
552
}
553
}
554
```
555
556
## Naming and Ordering Annotations
557
558
### @JsonNaming
559
560
Specifies property naming strategy.
561
562
```java { .api }
563
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
564
@Retention(RetentionPolicy.RUNTIME)
565
@JacksonAnnotation
566
public @interface JsonNaming {
567
// Naming strategy class
568
Class<? extends PropertyNamingStrategy> value();
569
}
570
```
571
572
### @JsonPropertyOrder
573
574
Controls the order of properties in serialization.
575
576
```java { .api }
577
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
578
@Retention(RetentionPolicy.RUNTIME)
579
@JacksonAnnotation
580
public @interface JsonPropertyOrder {
581
// Property names in desired order
582
String[] value() default {};
583
584
// Whether to order alphabetically
585
boolean alphabetic() default false;
586
}
587
```
588
589
### @EnumNaming
590
591
Specifies enum naming strategy.
592
593
```java { .api }
594
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
595
@Retention(RetentionPolicy.RUNTIME)
596
@JacksonAnnotation
597
public @interface EnumNaming {
598
// Enum naming strategy class
599
Class<? extends EnumNamingStrategy> value();
600
}
601
```
602
603
## Filter and View Annotations
604
605
### @JsonFilter
606
607
Associates a filter ID with a class.
608
609
```java { .api }
610
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
611
@Retention(RetentionPolicy.RUNTIME)
612
@JacksonAnnotation
613
public @interface JsonFilter {
614
// Filter ID
615
String value();
616
}
617
```
618
619
### @JsonView
620
621
Controls which properties are included in different views.
622
623
```java { .api }
624
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
625
@Retention(RetentionPolicy.RUNTIME)
626
@JacksonAnnotation
627
public @interface JsonView {
628
// View classes
629
Class<?>[] value();
630
}
631
```
632
633
## Specialized Annotations
634
635
### @JsonAppend
636
637
Adds virtual properties during serialization.
638
639
```java { .api }
640
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
641
@Retention(RetentionPolicy.RUNTIME)
642
@JacksonAnnotation
643
public @interface JsonAppend {
644
// Attribute properties
645
JsonAppend.Attr[] attrs() default {};
646
647
// Regular properties
648
JsonAppend.Prop[] props() default {};
649
650
// Prepend vs append
651
boolean prepend() default false;
652
653
// Attribute property
654
@Target({})
655
@Retention(RetentionPolicy.RUNTIME)
656
public @interface Attr {
657
String value();
658
boolean required() default false;
659
Class<? extends JsonSerializer> serializer() default JsonSerializer.None.class;
660
}
661
662
// Virtual property
663
@Target({})
664
@Retention(RetentionPolicy.RUNTIME)
665
public @interface Prop {
666
Class<?> value();
667
String name() default "";
668
String namespace() default "";
669
boolean required() default false;
670
int index() default -1;
671
}
672
}
673
```
674
675
### @JsonRootName
676
677
Specifies root element name for root wrapping.
678
679
```java { .api }
680
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
681
@Retention(RetentionPolicy.RUNTIME)
682
@JacksonAnnotation
683
public @interface JsonRootName {
684
// Root element name
685
String value() default "";
686
687
// Namespace
688
String namespace() default "";
689
}
690
```
691
692
### @JsonClassDescription
693
694
Provides description for schema generation.
695
696
```java { .api }
697
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
698
@Retention(RetentionPolicy.RUNTIME)
699
@JacksonAnnotation
700
public @interface JsonClassDescription {
701
// Description text
702
String value();
703
}
704
705
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
706
@Retention(RetentionPolicy.RUNTIME)
707
@JacksonAnnotation
708
public @interface JsonPropertyDescription {
709
// Description text
710
String value();
711
}
712
```
713
714
## Usage Examples
715
716
### Basic Property Control
717
718
```java
719
import com.fasterxml.jackson.annotation.*;
720
721
public class User {
722
// Custom property name
723
@JsonProperty("user_id")
724
private Long id;
725
726
// Required property
727
@JsonProperty(required = true)
728
private String username;
729
730
// Read-only property
731
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
732
private Date createdAt;
733
734
// Ignored property
735
@JsonIgnore
736
private String password;
737
738
// Conditional inclusion
739
@JsonInclude(JsonInclude.Include.NON_NULL)
740
private String email;
741
742
// Custom format
743
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
744
private Date lastLogin;
745
746
// Constructor for deserialization
747
@JsonCreator
748
public User(@JsonProperty("user_id") Long id,
749
@JsonProperty("username") String username) {
750
this.id = id;
751
this.username = username;
752
}
753
754
// Custom getter name
755
@JsonGetter("full_name")
756
public String getDisplayName() {
757
return firstName + " " + lastName;
758
}
759
760
// Custom setter with null handling
761
@JsonSetter(value = "email", nulls = JsonSetter.Nulls.SKIP)
762
public void setEmailAddress(String email) {
763
this.email = email != null ? email.toLowerCase() : null;
764
}
765
}
766
```
767
768
### Advanced Serialization Control
769
770
```java
771
// Custom serializers and property ordering
772
@JsonPropertyOrder({"id", "name", "status", "createdAt"})
773
@JsonInclude(JsonInclude.Include.NON_EMPTY)
774
public class Product {
775
private Long id;
776
private String name;
777
778
// Custom serialization
779
@JsonSerialize(using = MoneySerializer.class)
780
private BigDecimal price;
781
782
// Custom deserialization
783
@JsonDeserialize(using = StatusDeserializer.class)
784
private ProductStatus status;
785
786
// Converter usage
787
@JsonSerialize(converter = CategoryToStringConverter.class)
788
@JsonDeserialize(converter = StringToCategoryConverter.class)
789
private Category category;
790
791
// Null handling
792
@JsonSetter(nulls = JsonSetter.Nulls.AS_EMPTY)
793
private List<String> tags = new ArrayList<>();
794
795
// Builder support
796
@JsonPOJOBuilder(withPrefix = "set", buildMethodName = "create")
797
public static class Builder {
798
private Product product = new Product();
799
800
public Builder setId(Long id) {
801
product.id = id;
802
return this;
803
}
804
805
public Builder setName(String name) {
806
product.name = name;
807
return this;
808
}
809
810
public Product create() {
811
return product;
812
}
813
}
814
}
815
816
// Custom serializer
817
public class MoneySerializer extends JsonSerializer<BigDecimal> {
818
@Override
819
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
820
gen.writeString("$" + value.setScale(2, RoundingMode.HALF_UP));
821
}
822
}
823
```
824
825
### Polymorphic Types
826
827
```java
828
// Base class with type information
829
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
830
@JsonSubTypes({
831
@JsonSubTypes.Type(value = Circle.class, name = "circle"),
832
@JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"),
833
@JsonSubTypes.Type(value = Triangle.class, name = "triangle")
834
})
835
public abstract class Shape {
836
@JsonProperty
837
protected String color;
838
839
// Common properties and methods
840
}
841
842
@JsonTypeName("circle")
843
public class Circle extends Shape {
844
@JsonProperty
845
private double radius;
846
847
@JsonCreator
848
public Circle(@JsonProperty("radius") double radius) {
849
this.radius = radius;
850
}
851
}
852
853
@JsonTypeName("rectangle")
854
public class Rectangle extends Shape {
855
@JsonProperty
856
private double width;
857
858
@JsonProperty
859
private double height;
860
861
@JsonCreator
862
public Rectangle(@JsonProperty("width") double width, @JsonProperty("height") double height) {
863
this.width = width;
864
this.height = height;
865
}
866
}
867
868
// Usage
869
Shape shape = new Circle(5.0);
870
String json = mapper.writeValueAsString(shape);
871
// Result: {"type":"circle","color":null,"radius":5.0}
872
873
Shape parsed = mapper.readValue(json, Shape.class); // Returns Circle instance
874
```
875
876
### Object Identity and References
877
878
```java
879
// Using object identity to handle circular references
880
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
881
public class Department {
882
private Long id;
883
private String name;
884
885
@JsonManagedReference("department-employees")
886
private List<Employee> employees = new ArrayList<>();
887
}
888
889
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
890
public class Employee {
891
private Long id;
892
private String name;
893
894
@JsonBackReference("department-employees")
895
private Department department;
896
897
@JsonManagedReference("employee-tasks")
898
private List<Task> tasks = new ArrayList<>();
899
}
900
901
public class Task {
902
private Long id;
903
private String description;
904
905
@JsonBackReference("employee-tasks")
906
private Employee assignee;
907
}
908
909
// This prevents infinite recursion and duplicate serialization
910
Department dept = new Department();
911
dept.setId(1L);
912
Employee emp = new Employee();
913
emp.setId(100L);
914
emp.setDepartment(dept);
915
dept.getEmployees().add(emp);
916
917
String json = mapper.writeValueAsString(dept);
918
// Uses object IDs to represent relationships efficiently
919
```
920
921
### Dynamic Properties
922
923
```java
924
public class FlexibleEntity {
925
private String name;
926
private String type;
927
928
// Store unknown properties
929
private Map<String, Object> additionalProperties = new HashMap<>();
930
931
@JsonAnyGetter
932
public Map<String, Object> getAdditionalProperties() {
933
return additionalProperties;
934
}
935
936
@JsonAnySetter
937
public void setAdditionalProperty(String key, Object value) {
938
additionalProperties.put(key, value);
939
}
940
941
// Getters/setters for known properties
942
}
943
944
// This class can handle JSON with unknown properties:
945
String json = """
946
{
947
"name": "Sample",
948
"type": "test",
949
"customField1": "value1",
950
"customField2": 123,
951
"nested": {"key": "value"}
952
}
953
""";
954
955
FlexibleEntity entity = mapper.readValue(json, FlexibleEntity.class);
956
// entity.getAdditionalProperties() contains the unknown properties
957
```
958
959
### Unwrapping and Nested Objects
960
961
```java
962
public class Address {
963
private String street;
964
private String city;
965
private String zipCode;
966
// getters/setters
967
}
968
969
public class Person {
970
private String name;
971
private int age;
972
973
// Unwrap address fields directly into person JSON
974
@JsonUnwrapped
975
private Address address;
976
977
// Unwrap with prefix
978
@JsonUnwrapped(prefix = "work_")
979
private Address workAddress;
980
}
981
982
// Serialization result:
983
// {
984
// "name": "John",
985
// "age": 30,
986
// "street": "123 Main St", // from address
987
// "city": "Springfield",
988
// "zipCode": "12345",
989
// "work_street": "456 Office Blvd", // from workAddress with prefix
990
// "work_city": "Business City",
991
// "work_zipCode": "67890"
992
// }
993
```
994
995
### Views and Filtering
996
997
```java
998
// Define view classes
999
public class Views {
1000
public static class Public {}
1001
public static class Internal extends Public {}
1002
public static class Admin extends Internal {}
1003
}
1004
1005
public class UserRecord {
1006
@JsonView(Views.Public.class)
1007
private String name;
1008
1009
@JsonView(Views.Public.class)
1010
private String email;
1011
1012
@JsonView(Views.Internal.class)
1013
private String department;
1014
1015
@JsonView(Views.Admin.class)
1016
private BigDecimal salary;
1017
1018
@JsonView(Views.Admin.class)
1019
private String ssn;
1020
}
1021
1022
// Usage with different views
1023
ObjectWriter publicWriter = mapper.writerWithView(Views.Public.class);
1024
ObjectWriter internalWriter = mapper.writerWithView(Views.Internal.class);
1025
ObjectWriter adminWriter = mapper.writerWithView(Views.Admin.class);
1026
1027
UserRecord user = new UserRecord("John", "john@example.com", "Engineering", new BigDecimal("75000"), "123-45-6789");
1028
1029
String publicJson = publicWriter.writeValueAsString(user);
1030
// Only name and email
1031
1032
String internalJson = internalWriter.writeValueAsString(user);
1033
// name, email, and department
1034
1035
String adminJson = adminWriter.writeValueAsString(user);
1036
// All fields
1037
```
1038
1039
### Custom Annotations
1040
1041
```java
1042
// Create custom annotation
1043
@Target(ElementType.FIELD)
1044
@Retention(RetentionPolicy.RUNTIME)
1045
@JsonSerialize(using = SensitiveDataSerializer.class)
1046
public @interface SensitiveData {
1047
// Masking strategy
1048
MaskStrategy strategy() default MaskStrategy.ASTERISK;
1049
1050
enum MaskStrategy {
1051
ASTERISK, HASH, REDACTED
1052
}
1053
}
1054
1055
// Custom serializer that reads the annotation
1056
public class SensitiveDataSerializer extends JsonSerializer<String> {
1057
1058
@Override
1059
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
1060
// Get the property being serialized
1061
BeanProperty property = (BeanProperty) serializers.getAttribute("CURRENT_PROPERTY");
1062
1063
if (property != null) {
1064
SensitiveData annotation = property.getAnnotation(SensitiveData.class);
1065
if (annotation != null) {
1066
String masked = maskValue(value, annotation.strategy());
1067
gen.writeString(masked);
1068
return;
1069
}
1070
}
1071
1072
gen.writeString(value);
1073
}
1074
1075
private String maskValue(String value, SensitiveData.MaskStrategy strategy) {
1076
if (value == null || value.length() < 3) {
1077
return "***";
1078
}
1079
1080
return switch (strategy) {
1081
case ASTERISK -> value.substring(0, 2) + "*".repeat(value.length() - 2);
1082
case HASH -> value.substring(0, 2) + "#".repeat(value.length() - 2);
1083
case REDACTED -> "[REDACTED]";
1084
};
1085
}
1086
}
1087
1088
// Usage
1089
public class Account {
1090
private String accountNumber;
1091
1092
@SensitiveData(strategy = SensitiveData.MaskStrategy.ASTERISK)
1093
private String creditCardNumber;
1094
1095
@SensitiveData(strategy = SensitiveData.MaskStrategy.REDACTED)
1096
private String ssn;
1097
}
1098
```
1099
1100
## Types
1101
1102
```java { .api }
1103
// Base Jackson annotation interface
1104
public interface JacksonAnnotation {
1105
// Marker interface for all Jackson annotations
1106
}
1107
1108
// Converter interface for @JsonSerialize/@JsonDeserialize converter elements
1109
public interface Converter<IN, OUT> {
1110
OUT convert(IN value);
1111
JavaType getInputType(TypeFactory typeFactory);
1112
JavaType getOutputType(TypeFactory typeFactory);
1113
1114
// Marker class for no converter
1115
public static abstract class None implements Converter<Object, Object> { }
1116
}
1117
1118
// Standard converter implementations
1119
public abstract class StdConverter<IN, OUT> implements Converter<IN, OUT> {
1120
public abstract OUT convert(IN value);
1121
public JavaType getInputType(TypeFactory typeFactory);
1122
public JavaType getOutputType(TypeFactory typeFactory);
1123
}
1124
1125
// Object ID generators for @JsonIdentityInfo
1126
public abstract class ObjectIdGenerator<T> implements Serializable {
1127
public abstract Class<?> getScope();
1128
public abstract boolean canUseFor(ObjectIdGenerator<?> gen);
1129
public abstract ObjectIdGenerator<T> forScope(Class<?> scope);
1130
public abstract ObjectIdGenerator<T> newForSerialization(Object context);
1131
public abstract IdKey key(Object key);
1132
public abstract T generateId(Object forPojo);
1133
}
1134
1135
// Standard object ID generators
1136
public class ObjectIdGenerators {
1137
public static class IntSequenceGenerator extends ObjectIdGenerator<Integer> { }
1138
public static class PropertyGenerator extends ObjectIdGenerator<Object> { }
1139
public static class StringIdGenerator extends ObjectIdGenerator<String> { }
1140
public static class UUIDGenerator extends ObjectIdGenerator<UUID> { }
1141
}
1142
1143
// Property naming strategies for @JsonNaming
1144
public abstract class PropertyNamingStrategy implements Serializable {
1145
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName);
1146
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName);
1147
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName);
1148
public String nameForConstructorParameter(MapperConfig<?> config, AnnotatedParameter ctorParam, String defaultName);
1149
}
1150
1151
// Standard naming strategies
1152
public abstract class PropertyNamingStrategies {
1153
public static final PropertyNamingStrategy LOWER_CAMEL_CASE;
1154
public static final PropertyNamingStrategy UPPER_CAMEL_CASE;
1155
public static final PropertyNamingStrategy SNAKE_CASE;
1156
public static final PropertyNamingStrategy UPPER_SNAKE_CASE;
1157
public static final PropertyNamingStrategy LOWER_CASE;
1158
public static final PropertyNamingStrategy KEBAB_CASE;
1159
public static final PropertyNamingStrategy LOWER_DOT_CASE;
1160
}
1161
1162
// Enum naming strategies for @EnumNaming
1163
public interface EnumNamingStrategy {
1164
String convertEnumToExternalName(String enumName);
1165
}
1166
1167
public class EnumNamingStrategies {
1168
public static final EnumNamingStrategy LOWER_CAMEL_CASE;
1169
public static final EnumNamingStrategy UPPER_CAMEL_CASE;
1170
public static final EnumNamingStrategy SNAKE_CASE;
1171
public static final EnumNamingStrategy UPPER_SNAKE_CASE;
1172
public static final EnumNamingStrategy LOWER_CASE;
1173
public static final EnumNamingStrategy KEBAB_CASE;
1174
}
1175
```