37 runnable examples covering the eight feature posts on ankurm.com, verified against Jackson 3.2.1 on Temurin 21.0.5. Every output committed under docs/ was produced by run-all.sh. Also documents 11 places where the published snippets do not compile or do not behave as printed against a real Jackson 3 build - most notably that writeValueAsString(List<Base>) silently drops the polymorphic type discriminator, so the post's serialised output cannot be read back.
75 lines
3.1 KiB
Markdown
75 lines
3.1 KiB
Markdown
# Part 3 — Annotations
|
|
|
|
Post: <https://ankurm.com/jackson-annotations-guide/>
|
|
|
|
Every `@Json*` annotation is imported from `com.fasterxml.jackson.annotation`, even in
|
|
Jackson 3. `jackson-annotations` deliberately keeps the old group ID and package so a
|
|
single copy can serve Jackson 2 and Jackson 3 code on one classpath — the
|
|
[migration repo's coexistence module](https://ankurm.com/git.app/asmhatre/jackson2-to-3-migration)
|
|
proves that with both majors loaded at once.
|
|
|
|
## D01 — @JsonProperty and @JsonIgnore
|
|
|
|
[`D01RenameAndIgnore.java`](../src/main/java/com/ankurm/jackson3/part3annotations/D01RenameAndIgnore.java)
|
|
|
|
```
|
|
rename : {"order_id":1001,"customer_name":"Alice"}
|
|
read back : OrderSummary[orderId=1001, customerName=Alice]
|
|
ignore : {"username":"alice"}
|
|
read back : passwordHash=null
|
|
```
|
|
|
|
`@JsonIgnore` is bidirectional — the last line shows an injected `passwordHash` in the
|
|
input being discarded, which is the security-relevant half people forget.
|
|
|
|
## D02 — @JsonInclude and @JsonFormat
|
|
|
|
[`D02InclusionAndFormat.java`](../src/main/java/com/ankurm/jackson3/part3annotations/D02InclusionAndFormat.java)
|
|
|
|
```
|
|
NON_NULL : {"productName":"Keyboard"}
|
|
NON_EMPTY : {"productName":"Keyboard"}
|
|
formats : {"invoiceId":500,"defaultDate":"2026-04-09","ukStyleDate":"09/04/2026","totalAmount":"199.99"}
|
|
```
|
|
|
|
`defaultDate` carries no annotation and still comes out as `2026-04-09`. The post's
|
|
claim that "without `@JsonFormat`, Jackson writes `LocalDate` as a numeric array" was
|
|
true in Jackson 2; in Jackson 3 ISO-8601 is the default and the annotation is only
|
|
needed for a non-standard pattern such as `ukStyleDate`.
|
|
|
|
## D03 — @JsonAlias and unknown fields
|
|
|
|
[`D03AliasAndUnknownFields.java`](../src/main/java/com/ankurm/jackson3/part3annotations/D03AliasAndUnknownFields.java)
|
|
|
|
```
|
|
alias {"q":"jackson"} -> jackson
|
|
alias {"query":"jackson"} -> jackson
|
|
alias {"search_term":"jackson"} -> jackson
|
|
default mapper : LenientResponse[status=OK, message=done]
|
|
strict mapper : UnrecognizedPropertyException (as expected)
|
|
strict + anno : OptedOutResponse[status=OK, message=done]
|
|
```
|
|
|
|
The post frames `@JsonIgnoreProperties(ignoreUnknown = true)` as the per-class
|
|
alternative to disabling `FAIL_ON_UNKNOWN_PROPERTIES` globally. In Jackson 3 that
|
|
feature is already off, so the default mapper tolerates the extra field with no
|
|
annotation. The annotation earns its keep only on a mapper where you have deliberately
|
|
re-enabled strictness — which is the `strict` case above.
|
|
|
|
## D04 — creators, unwrapping and catch-alls
|
|
|
|
[`D04CreatorsAndUnwrapping.java`](../src/main/java/com/ankurm/jackson3/part3annotations/D04CreatorsAndUnwrapping.java)
|
|
|
|
`@JsonUnwrapped` appears in the post's summary table but is never demonstrated;
|
|
`@JsonAnyGetter`/`@JsonAnySetter` are not in the post at all, and are the cleanest way
|
|
to keep fields you did not model instead of silently dropping them.
|
|
|
|
```
|
|
creator : ImmutablePoint(x=3.5, y=7.2)
|
|
round-trip: {"x":3.5,"y":7.2}
|
|
unwrapped : {"street":"123 Main St","city":"Springfield","customerName":"Alice"}
|
|
any-setter: {surprise=1, another=[true, false]}
|
|
any-getter: {"knownField":"a","surprise":1,"another":[true,false]}
|
|
```
|
|
|