How to Exclude Fields in JSON Serialization (But Not Deserialization) Using @JsonIgnore

Fields in JSON Serialization

Struggling to hide sensitive fields like passwords in JSON responses—without breaking user registration? In this guide, you’ll learn how to use @JsonIgnore for serialization only, so you can hide data in output while still accepting it during deserialization.

We’ll walk through two battle-tested solutions, step-by-step implementation, and security best practices.


Table of Contents

  1. Why @JsonIgnore Blocks Both Directions
  2. Fix #1: @JsonIgnore + @JsonProperty Combo
  3. Fix #2: @JsonProperty(access = WRITE_ONLY)
  4. Step-by-Step Setup
  5. Best Practices for Secure Serialization
  6. FAQs
  7. Conclusion

Why @JsonIgnore Blocks Both Serialization and Deserialization

By default, when you annotate a field with @JsonIgnore, Jackson ignores it in both serialization (outbound JSON) and deserialization (inbound JSON).

Example

public class User {
    @JsonIgnore // ❌ Blocks field in both directions
    private String password;
}

Result:

  • ✅ Password is excluded from JSON responses
  • ❌ Password is also ignored in incoming requests—breaking sign-up logic

This becomes a major issue when registering users or handling sensitive input.

JsonIgnore serialization vs deserialization diagram
Alt Text: JsonIgnore serialization not deserialization flow in Java


Fix #1: Use @JsonIgnore on Getter and @JsonProperty on Setter

Strategy

  • Use @JsonIgnore on the getter to skip the field during serialization.
  • Use @JsonProperty on the setter to accept the field during deserialization.
public class User {
    private String password;

    @JsonIgnore // Prevent field in JSON output
    public String getPassword() {
        return password;
    }

    @JsonProperty // Allow field in JSON input
    public void setPassword(String password) {
        this.password = password;
    }
}

Compatible with all Jackson versions
✅ Ideal if you’re using POJOs with custom getters/setters


Fix #2: Use @JsonProperty(access = WRITE_ONLY) (Jackson 2.6+)

This newer approach is cleaner if you’re using Jackson 2.6 or higher.

public class User {
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) // ✅ Deserialization only
    private String password;
}

Benefits

  • No need for custom methods
  • Cleaner, more declarative syntax
  • Easier to document and maintain

📌 Important: Ensure you’re using Jackson 2.6+ in your project.


Step-by-Step Setup Guide

Step 1: Add Jackson Dependency

For Maven:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.13.0</version>
</dependency>

Step 2: Annotate the Field

Use either solution depending on your Jackson version:

Option 1:

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;

Option 2:

@JsonIgnore
public String getPassword() { return password; }

@JsonProperty
public void setPassword(String password) { this.password = password; }

Step 3: Validate with Unit Tests

@Test
void serializeUser_ExcludesPassword() throws Exception {
    User user = new User("john", "secret");
    String json = new ObjectMapper().writeValueAsString(user);
    assertFalse(json.contains("secret")); // ✅ Password hidden
}

@Test
void deserializeUser_IncludesPassword() throws Exception {
    String json = "{\"username\":\"john\",\"password\":\"secret\"}";
    User user = new ObjectMapper().readValue(json, User.class);
    assertEquals("secret", user.getPassword()); // ✅ Password read
}

Best Practices for Secure JSON Serialization

  1. Never expose sensitive data in API responses—especially fields like password, tokens, or SSNs.
  2. Use DTOs to isolate external-facing models from your internal entities.
  3. Validate input on deserialization (e.g., minimum password strength).
  4. Keep Jackson updated to use the latest features like WRITE_ONLY.

🔗 Spring Security Best Practices for APIs


FAQs

❓ Does @JsonIgnore block both directions?

Yes, it affects both serialization and deserialization. Use it carefully—preferably only on getters or with another annotation.

❓ What’s the difference between @JsonIgnore and @JsonProperty(access = WRITE_ONLY)?

  • @JsonIgnore: Ignores the field entirely.
  • @JsonProperty(access = WRITE_ONLY): Allows write (input) only; skips during output.

❓ Can I use these annotations with Lombok?

Absolutely. You can combine Lombok with Jackson like this:

@Data
public class User {
    @Getter(onMethod_ = @JsonIgnore)
    @Setter(onMethod_ = @JsonProperty)
    private String password;
}

Conclusion

Mastering @JsonIgnore for serialization-only scenarios is key to building secure, functional APIs. Whether you use the getter/setter method or the cleaner WRITE_ONLY annotation, you’ll prevent sensitive data from leaking—while keeping your app’s features intact.

🔐 Build secure. Ship with confidence.


External Resource:

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *