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
- Why @JsonIgnore Blocks Both Directions
- Fix #1: @JsonIgnore + @JsonProperty Combo
- Fix #2: @JsonProperty(access = WRITE_ONLY)
- Step-by-Step Setup
- Best Practices for Secure Serialization
- FAQs
- 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.
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
- Never expose sensitive data in API responses—especially fields like
password
,tokens
, orSSNs
. - Use DTOs to isolate external-facing models from your internal entities.
- Validate input on deserialization (e.g., minimum password strength).
- 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: