package com.ankurm.jackson3.part3annotations; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import tools.jackson.databind.DeserializationFeature; import tools.jackson.databind.json.JsonMapper; /** * Post: Jackson Annotations Cheat Sheet — https://ankurm.com/jackson-annotations-guide/ * Sections: "@JsonAlias" and "@JsonIgnoreProperties" * * Correction to the post: it frames @JsonIgnoreProperties(ignoreUnknown = true) as the * per-class alternative to configuring FAIL_ON_UNKNOWN_PROPERTIES globally. In Jackson 3 * that feature is already DISABLED by default, so unknown fields are tolerated with no * annotation at all. The annotation now matters mainly when you have deliberately turned * strictness back ON — which is what the `strict` mapper below does. */ public class D03AliasAndUnknownFields { public record SearchQuery( @JsonAlias({ "q", "query", "search_term" }) String searchKeyword) { } public record LenientResponse(String status, String message) { } @JsonIgnoreProperties(ignoreUnknown = true) public record OptedOutResponse(String status, String message) { } public static void main(String[] args) { JsonMapper mapper = JsonMapper.builder().build(); for (String json : new String[] { "{\"q\":\"jackson\"}", "{\"query\":\"jackson\"}", "{\"search_term\":\"jackson\"}" }) { System.out.println("alias " + String.format("%-24s", json) + " -> " + mapper.readValue(json, SearchQuery.class).searchKeyword()); } String extra = "{\"status\":\"OK\",\"message\":\"done\",\"undocumentedField\":42}"; // Default Jackson 3 mapper: unknown fields are already ignored. System.out.println("default mapper : " + mapper.readValue(extra, LenientResponse.class)); // A mapper with strictness deliberately re-enabled. JsonMapper strict = JsonMapper.builder() .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); try { strict.readValue(extra, LenientResponse.class); System.out.println("strict mapper : unreachable"); } catch (Exception e) { System.out.println("strict mapper : " + e.getClass().getSimpleName() + " (as expected)"); } // ...but the annotation opts this one class back out of the strictness. System.out.println("strict + anno : " + strict.readValue(extra, OptedOutResponse.class)); } }