Skip to content

How to Exclude Null Values from Spring Boot REST JSON Responses

Purpose

This post demonstrates how to exclude null values from Spring Boot REST JSON responses to reduce payload size and improve API performance.

Environment

  • Spring Boot 3.2.0
  • Java 17
  • Jackson 2.15.2
  • Maven 3.9.0

The Problem

When I built a REST API for a user management system, I noticed the JSON responses included many null fields for optional properties. This made the responses cluttered and larger than necessary.

Here’s my User entity:

src/main/java/com/example/demo/entity/User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String phone; // Optional
private String address; // Optional
private String bio; // Optional
private String avatar; // Optional
// Constructors, getters, setters
}

Here’s the REST controller:

src/main/java/com/example/demo/controller/UserController.java
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}

When I called GET /api/users/1, I got this response:

{
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"phone": null,
"address": null,
"bio": null,
"avatar": null
}

The response included 5 null fields. This wastes bandwidth and makes the response harder to read. For mobile apps on slow networks, every byte matters.

The Solution

I found that Spring Boot uses Jackson for JSON serialization by default. Jackson provides a configuration option to exclude null values from JSON output.

The simplest way is to add one line to application.yml:

src/main/resources/application.yml
spring:
jackson:
default-property-inclusion: non_null

Or if you use application.properties:

src/main/resources/application.properties
spring.jackson.default-property-inclusion=non_null

I added this to my config and restarted the application. When I called the same endpoint again, I got:

{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}

The null fields disappeared without any code changes. This configuration applies to all REST endpoints globally.

Method 2: Class-Level Annotation

When I wanted to control null exclusion per class, I used the @JsonInclude annotation:

src/main/java/com/example/demo/entity/User.java
@Entity
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String phone;
private String address;
// Constructors, getters, setters
}

This worked well for the User class, but I had to add the annotation to every entity class.

Method 3: Field-Level Annotation

For more granular control, I applied the annotation to specific fields:

src/main/java/com/example/demo/entity/User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
@JsonInclude(JsonInclude.Include.NON_NULL)
private String phone;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<String> tags;
// Constructors, getters, setters
}

This approach gave me fine-grained control, but it became verbose for entities with many optional fields.

How It Works

Jackson’s JsonInclude.Include enum provides several options:

  • ALWAYS: Include all values regardless of null or empty
  • NON_NULL: Don’t include properties with null values
  • NON_EMPTY: Don’t include properties with null or empty values (collections, strings)
  • NON_DEFAULT: Don’t include properties with default values

I tried using NON_EMPTY to exclude empty collections:

src/main/resources/application.yml
spring:
jackson:
default-property-inclusion: non_empty

With this config, both null AND empty values are excluded:

{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
// "tags": [] would also be excluded
// "bio": "" would also be excluded
}

But I found this could break client code that expects arrays, even empty ones. So I stuck with NON_NULL for most cases.

Common Mistakes

I made a few mistakes while implementing this:

1. Using NON_EMPTY when clients expect arrays

I initially used non_empty globally. This broke the frontend when it tried to iterate over a missing tags array. The frontend expected an empty array [], not a missing field. I switched back to non_null for collection fields.

2. Mixing global and annotation-based config

I used non_null globally but added @JsonInclude(JsonInclude.Include.ALWAYS) on some fields. This created confusion about which configuration took precedence. I learned that annotations override global settings, so I either used one approach or the other consistently.

3. Not updating API documentation

After enabling null exclusion, I forgot to update the API docs. This confused frontend developers who expected null fields. I updated the OpenAPI specification to document that null fields are omitted from responses.

4. Breaking existing clients

When I added null exclusion to an existing API, it broke mobile apps that relied on null fields being present. I learned to document this change in the API changelog and version the endpoint.

Why This Matters

Excluding null values from JSON responses provides real benefits:

  1. Reduced payload size: For the User entity, excluding 5 null fields reduced the JSON size from 160 bytes to 70 bytes - a 56% reduction.

  2. Improved mobile performance: Smaller responses mean faster API calls and better battery life on mobile devices.

  3. Cleaner API contracts: Responses only contain meaningful data, making API documentation clearer.

  4. Simplified client code: Frontend developers don’t need to check for nulls as frequently when accessing fields.

Summary

In this post, I showed how to exclude null values from Spring Boot REST JSON responses using Jackson’s default-property-inclusion configuration. The key point is that a single line in application.yml can reduce payload size and improve API performance across all endpoints.

For most projects, I recommend using the global spring.jackson.default-property-inclusion=non_null configuration. Use @JsonInclude annotations only when you need per-class or per-field control.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments