Tuesday 10 December 2019

Use SpEL to Conditionally Suppress JSON Fields During Serialisation

If you use the Jackson Framework to serialise objects to Json, exposed through a Spring REST API,  then you might often come across a requirement to suppress the field dynamically during serialisation when a condition is met. This example shows how to extend the framework by implementing the PropertyFilter stereotype to use Spring Expression Language (SpEL) expressions to conditionally write out the field and value at the point of serialisation.



The Jackson framework provides customisation to conditionally filter out Java object values with the PropertyFilter interface. This is implemented within the framework as a BeanPropertyFilter and SimpleBeanPropertyFilter which provides some static functions to filter out different properties on the target bean being serialised. This is accomplished by adding the filter to the Object Mapper within the context and then telling Jackson to apply that filter to certain beans by annotating the bean class with the JsonFilter stereotype .

These basic functions are useful but don't allow the developer to provide any more complex conditions and logic. For example, you might wish to only include an integer Json field and value in output if the value in the object is greater than a predefined value.

Spring Expression Language is perfect for this job; it provides a framework to inject complex conditional logic through an expression represented as a String. Using this in a new annotation which can be added to serializable beans will allow us to easily define expressions which conditionally suppress Json properties.

I first created a new stereotype to mark a Java field and define an expression used during serialisation.



I then created an implementation of the Jackson PropertyFilter interface which looks for fields marked for conditional suppression and applies the expression to that field value.



The function injects the bean instance into the SpEL evaluation context and ensures that the expression evaluates as a boolean and throws out a SpEL Exception with an appropriate error code if not.

SpEL provides convenient syntax to refer to values within the context at runtime. However, typing these out in an expression specifically for a field seems overly clunky so I abbreviated that syntax with a substitute character and replaced it during the evaluation.



I added some further configuration to ensure the SpEL Filter is injected into the Object Mapper in the Spring Context, whether it's already there or not, and an annotation to enable the functionality.



The filter works as intended. When coupled with the existing JsonFilter annotation it is very easy to define complex logic which conditionally suppresses Json elements.



The full source can be found on my public GitHub or integrated into your project directly from Jitpack