Core Java

How to Dynamically Ignore Fields in Jackson

Jackson is a popular Java library for JSON processing. Sometimes, we need to ignore fields dynamically at runtime instead of using static annotations like @JsonIgnore. This article explores various approaches to dynamically ignoring fields in Jackson.

1. Default Behavior and Static Field Ignoring

Before handling dynamic field ignoring, let’s see Jackson’s default behaviour and how fields are statically ignored.

1.1 Default Behavior

By default, Jackson serializes all fields of a Java object unless explicitly ignored.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public class Product {
 
    private String name;
    private double price;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public double getPrice() {
        return price;
    }
 
    public void setPrice(double price) {
        this.price = price;
    }  
}
01
02
03
04
05
06
07
08
09
10
11
12
public class DefaultSerialization {
 
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Product product = new Product();
        product.setName("Laptop");
        product.setPrice(1200.50);
 
        String json = mapper.writeValueAsString(product);
        System.out.println(json);
    }
}

Output:

1
{"name":"Laptop","price":1200.5}

1.2 Using @JsonIgnore to Statically Ignore Fields

If we want to always exclude a field, we can use @JsonIgnore.

1
2
3
4
5
6
7
8
9
import com.fasterxml.jackson.annotation.JsonIgnore;
 
public class Product {
 
    private String name;
     
    @JsonIgnore
    private double price;
}
01
02
03
04
05
06
07
08
09
10
11
12
public class StaticIgnore {
 
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Product product = new Product();
        product.setName("Laptop");
        product.setPrice(1200.50);
 
        String json = mapper.writeValueAsString(product);
        System.out.println(json);
    }
}

Output:

1
{"name":"Laptop"}

The @JsonIgnore annotation works well for static exclusions, but let’s explore dynamic approaches.

2. Dynamically Ignoring Fields in Jackson

2.1 Using SimpleBeanPropertyFilter and @JsonFilter

We can dynamically exclude fields using Jackson’s SimpleBeanPropertyFilter.

1
2
3
4
5
6
7
8
import com.fasterxml.jackson.annotation.JsonFilter;
 
@JsonFilter("dynamicFilter")
public class Product {
 
    private String name;
    private double price;
}

The @JsonFilter("dynamicFilter") annotation in the Product class enables dynamic field filtering during JSON serialization using Jackson. Unlike static annotations like @JsonIgnore, which permanently exclude fields, @JsonFilter allows selective exclusion at runtime. The filter name "dynamicFilter" serves as an identifier that can be referenced in a FilterProvider configuration.

This setup allows the ObjectMapper to apply different filtering rules dynamically, determining which fields to include or ignore based on specific conditions.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
 
 
public class DynamicFilterExample {
 
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setFilterProvider(new SimpleFilterProvider().addFilter(
                "dynamicFilter",
                SimpleBeanPropertyFilter.serializeAllExcept("price")
        ));
 
        Product product = new Product();
        product.setName("Laptop");
        product.setPrice(1200.50);
 
        String json = mapper.writeValueAsString(product);
        System.out.println(json);
    }
}

The DynamicFilterExample class above demonstrates how to use Jackson’s SimpleBeanPropertyFilter to dynamically ignore a field during JSON serialization. The ObjectMapper is configured with a SimpleFilterProvider, which applies the filter named "dynamicFilter", ensuring that all fields except "price" are serialized.

When a Product object is created with a name and price, the ObjectMapper processes it according to the filter, omitting the price field from the output.

Output:

1
{"name":"Laptop"}

3. Using Mixins for Dynamic Ignoring

Mixins let us override annotations at runtime without modifying the original class.

3.1 Define a mixin to ignore the price field

Mixins in Jackson provide a way to modify the serialization and deserialization behaviour of a class without altering its source code. By defining a separate interface and applying it at runtime, we can dynamically ignore specific fields.

1
2
3
4
5
6
7
import com.fasterxml.jackson.annotation.JsonIgnore;
 
public interface ProductMixin {
 
    @JsonIgnore
    double getPrice();
}

In this code, ProductMixin is an interface that applies the @JsonIgnore annotation to the getPrice() method instead of directly on the field. Since Jackson uses getters for serialization, this ensures that the price field is ignored in the JSON output while keeping the Product class unchanged.

By registering this mixin with an ObjectMapper, we can dynamically exclude the price field during serialization without modifying the original class, making this approach flexible and reusable for different contexts.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class MixinExample {
 
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(Product.class, ProductMixin.class);
 
        Product product = new Product();
        product.setName("Laptop");
        product.setPrice(1200.50);
 
        String json = mapper.writeValueAsString(product);
        System.out.println(json);
    }
}

In the MixinExample class, Jackson’s addMixIn method is used to dynamically modify the serialization behaviour of the Product class without changing its source code. The line mapper.addMixIn(Product.class, ProductMixin.class); associates the ProductMixin interface with the Product class, applying the annotations from the mixin to the target class.

Since ProductMixin marks the getPrice() method with @JsonIgnore, Jackson will exclude the price field from the JSON output when serializing a Product object.

Output:

1
{"name":"Laptop"}

4. Using @JsonView for Conditional Serialization

Jackson’s @JsonView allows controlling which fields are included in the serialized JSON output based on different visibility levels.

1
2
3
4
5
6
7
8
public class Views {
 
    static class Public {
    }
 
    static class Admin extends Public {
    }
}

The Views class defines two nested static classes, Public and Admin, which are used as Jackson JSON Views to control field visibility during serialization. The Admin class extends Public, meaning it inherits all the fields associated with the Public view while also allowing additional fields to be included specifically for the Admin view. When @JsonView(Views.Public.class) is applied to a field, it will be visible in both Public and Admin views, while fields annotated with @JsonView(Views.Admin.class) will only be serialized when the Admin view is explicitly used.

01
02
03
04
05
06
07
08
09
10
11
import com.fasterxml.jackson.annotation.JsonView;
 
public class Product {
 
    @JsonView(Views.Public.class)
    private String name;
     
    @JsonView(Views.Admin.class)
    private double price;
     
}

In the following example, we define a Product object and serialize it using both the Public and Admin views to demonstrate how Jackson filters fields dynamically.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class JacksonViewsExample {
 
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
 
        Product product = new Product();
        product.setName("Laptop");
        product.setPrice(1200.50);
 
        // Serialize with public view
        String publicJson = mapper.writerWithView(Views.Public.class).writeValueAsString(product);
        System.out.println("Public View: " + publicJson);
 
        // Serialize with admin view
        String adminJson = mapper.writerWithView(Views.Admin.class).writeValueAsString(product);
        System.out.println("Admin View: " + adminJson);
    }
}

In this code, an ObjectMapper is used to serialize a Product object using two different views. The writerWithView(Views.Public.class) ensures that only fields marked with @JsonView(Views.Public.class) are included in the output, while writerWithView(Views.Admin.class) includes fields for both Public and Admin views.

Output:

Java Jackson dynamic field ignore example output using @JsonView

5. Conclusion

In this article, we explored various approaches to dynamically ignoring fields in Jackson. We covered using @JsonFilter for runtime filtering, mixins for modifying serialization behaviour without altering the original class, and @JsonView to control field visibility. Each method provides flexibility in managing JSON output, making it easier to handle different serialization requirements in Java applications.

6. Download the Source Code

This article covered how to use Jackson in Java to dynamic ignore fields during JSON processing.

Download
You can download the full source code of this example here: java jackson fields dynamic ignore

Omozegie Aziegbe

Omos Aziegbe is a technical writer and web/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button