Explain Codes LogoExplain Codes Logo

Jackson: how to prevent field serialization

java
json-engineering
best-practices
security
Anton ShumikhinbyAnton Shumikhin·Oct 29, 2024
TLDR

To omit a field from serialization in Jackson, slap a @JsonIgnore on it. For a blanket, class-wide approach, wrap it up in @JsonIgnoreProperties and specify the fields to leave out.

Example with @JsonIgnore:

class Example { String included; @JsonIgnore // "You shall not serialize!" String excluded; }

Managing multiple fields or want external configuration? Use a mixin with @JsonIgnoreProperties:

@JsonIgnoreProperties({"excluded1", "excluded2"}) abstract class ExampleMixin {} ObjectMapper nobleKmapper = new ObjectMapper(); nobleKmapper.addMixIn(Example.class, ExampleMixin.class);

Special cases: Locking away the crown jewels

When you're dealing with the Coca-Cola formula (aka sensitive information, like a password), security and functionality need to walk hand-in-hand. Jackson annotations are your bouncers here; they'll let the right folks in and keep the riff-raff out.

@JsonIgnore and @JsonProperty: Sherlock and Watson

To accept but not divulge a field (like when a client updates a password), apply @JsonIgnore to the getter and @JsonProperty to the setter (like Sherlock hiding clues and Watson revealing solutions):

public class User { private String password; @JsonIgnore // Sherlock: Hides the crown jewels public String getPassword() { return password; } @JsonProperty // Watson: Helps update the crown jewels public void setPassword(String password) { this.password = password; } }

JsonProperty.Access.WRITE_ONLY: The VIP area

Jackson 2.6 gave us JsonProperty.Access.WRITE_ONLY, a velvet rope that lets VIPs (properties) out of the club (JSON output), but only bouncers (read operations) are allowed back in:

public class User { @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) // The VIP area private String password; }

Advanced tricks: More than just card tricks

Encrypted fields: The Enigma machine

To store an encrypted version of a field, @JsonProperty comes to the rescue on a custom getter:

public class SecureData { private String secret; @JsonProperty // The Bletchley Park of our class public String getEncryptedSecret() { return encrypt(secret); // Only Turing can decode this } private String encrypt(String input) { // ... return "encryptedData"; // Enigma machine output } }

JSON Views: Now you see me

To conditionally expose fields, initiate JSON Views protocol:

public class Viewable { // Class: Akin to a magic show interface Summary { } static class Detailed extends Summary { } @JsonView(Summary.class) // The magician's assistant public String getGeneralInfo() { return "general"; } @JsonView(Detailed.class) // The actual magician public String getDetailedInfo() { return "detailed"; } } // Specify the magic trick when serializing ObjectWriter writer = mapper.writerWithView(Viewable.Summary.class);

@JsonIgnoreProperties: The crystal ball

Using @JsonIgnoreProperties is like having a crystal ball for serialization and deserialization:

@JsonIgnoreProperties(ignoreUnknown = true) public class OptimizedClass { // Fields without an audience (explicit annotations) will exit the stage. }