How to hide null fields in response in Java

Introduction

――This time it is as the title ――It's a relatively tips-like post

background

――When I was making API, I thought that there was no way to drop each key name from Response when there was a field with null contents, so I will summarize what I investigated a little.

What you have prepared

immediately

--Try to create an appropriate DTO class

HelloDto.java


public class HelloDto {

    private String name;

    private Integer age;

    private String address;

    //Getter and constructor omitted

}

--Call appropriately

HelloController.java


public class HelloController {

    public HelloDto getHello() {
        return new HelloDto("tom", 21, null);
    }
}

――At this time, when I try to get the Response of HelloDto, it looks like this

hello.json


{
  "name": "tom",
  "age": 21,
  "address": null
}

――In this case, what if you want to drop the address together with the key name? ――By the way, even if you prepare a constructor with different arguments, it was useless because Response was filled with null and was not returned.

solution

--Resolve using jackson annotations --Specifically, just use @JsonInclude (JsonInclude.Include.NON_NULL)

HelloDto.java


public class HelloDto {

    private String name;

    private Integer age;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String address;

    //Getter and constructor omitted

}

--It disappeared safely

hello.json


{
  "name": "tom",
  "age": 21
}

--By the way, @JsonInclude (JsonInclude.Include) has NON_NULL and NON_EMPTY (there are others), and when I read the Javadoc

JsonInclude.java



        /**
         * Value that indicates that only properties with non-null
         * values are to be included.
         */
        NON_NULL,

        /**
         * Value that indicates that only properties with null value,
         * or what is considered empty, are not to be included.
         * Definition of emptiness is data type specific; see below
         * for details on actual handling.
         *<p>
         * Default emptiness for all types includes:
         *<ul>
         * <li><code>Null</code> values.</li>
         * <li>"Absent" values (see {@link #NON_ABSENT})</li>
         *</ul>
         * so that as baseline, "empty" set includes values that would be
         * excluded by both {@link #NON_NULL} and {@link #NON_ABSENT}.
         *<br>
         * Beyond this base, following types have additional empty values:
         *<ul>
         * <li>For {@link java.util.Collection}s and {@link java.util.Map}s,
         *    method <code>isEmpty()</code> is called;
         *   </li>
         * <li>For Java arrays, empty arrays are ones with length of 0
         *   </li>
         * <li>For Java {@link java.lang.String}s, <code>length()</code> is called,
         *   and return value of 0 indicates empty String
         *   </li>
         * </ul>
         *  and for other types, null values are excluded but other exclusions (if any).
         *<p>
         * Note that this default handling can be overridden by custom
         * <code>JsonSerializer</code> implementation: if method <code>isEmpty()</code>
         * is overridden, it will be called to see if non-null values are
         * considered empty (null is always considered empty).
         *<p>
         * Compatibility note: Jackson 2.6 included a wider range of "empty" values than
         * either earlier (up to 2.5) or later (2.7 and beyond) types; specifically:
         *<ul>
         * <li>Default values of primitive types (like <code>0</code> for `int`/`java.lang.Integer`
         *  and `false` for `bool`/`Boolean`)
         *  </li>
         * <li>Timestamp 0 for date/time types
         *  </li>
         *</ul>
         * With 2.7, definition has been tightened back to only containing types explained
         * above (null, absent, empty String, empty containers), and now
         * extended definition may be specified using {@link #NON_DEFAULT}.
         */
        NON_EMPTY,
    

――NON_EMPTY, in addition to the judgment condition of NON_NULL, can play even when it looks like null, and it can be used in collections. So, except for the case where you want to play only null, I think NON_EMPTY is fine ... ――By the way, even if you don't attach it to each field, you can use it as a class annotation.

HelloDto.java


@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class HelloDto {

    private String name;

    private Integer age;

    private String address;

    private List<String> friends;

    public HelloDto(String name, Integer age, String address, List<String> friends) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.friends = friends;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    public List<String> getFriends() {
        return friends;
    }
}

――Caller like this

HelloController.java



public class HelloController {

    public HelloDto getHello() {
        return new HelloDto("tom", 21, null, new ArrayList<>());
    }
}

--So, Response looks like this

hello.json


{
  "name": "tom",
  "age": 21
}

--It worked safely (⌒ ▽ ⌒)

Summary

-@JsonInclude is convenient --There may be few use cases, but in the case of BFF, if null is returned as FE, it may be useful when you want to drop the entire key name.

Referenced site

Recommended Posts

How to hide null fields in response in Java
How to hide scrollbars in WebView
How to use classes in Java?
How to name variables in Java
How to concatenate strings in java
How to implement date calculation in Java
How to implement Kalman filter in Java
Multilingual Locale in Java How to use Locale
How to do base conversion in Java
How to implement coding conventions in Java
How to embed Janus Graph in Java
How to get the date in java
[Java] How to test for null with JUnit
How to display a web page in Java
How to get Class from Element in Java
[Java] How to substitute Model Mapper in Jackson
How to solve an Expression Problem in Java
How to write Java String # getBytes in Kotlin?
How to access Java Private methods and fields
How to call functions in bulk with Java reflection
How to create a Java environment in just 3 seconds
[Java] How to omit the private constructor in Lombok
How to input / output IBM mainframe files in Java?
How to create a data URI (base64) in Java
How to generate / verify ID token in Java Memo
How to convert A to a and a to A using AND and OR in Java
How to convert a file to a byte array in Java
How to Git manage Java EE projects in Eclipse
Summary of how to implement default arguments in Java
How to write modern Java. Immutable Java, consider Null safety.
How to put old Java (8 series) in macOS 10.15 Catalina
Notes on how to use regular expressions in Java
[Java] How to use Map
How to lower java version
[Java] How to use Map
How to uninstall Java 8 (Mac)
How to use java Optional
How to minimize Java images
How to write java comments
How to hide args4j default
How to use java class
[Java] How to use Optional ②
[Java] How to use removeAll ()
[Java] How to display Wingdings
[Java] How to use string.format
How to use Java Map
How to set Java constants
How to use Java variables
How to convert Java radix
[Java] How to implement multithreading
[Java] How to use Optional ①
How to initialize Java array
How to get the class name / method name running in Java
How to read your own YAML file (*****. Yml) in Java
What happened in "Java 8 to Java 11" and how to build an environment
How to call and use API in Java (Spring Boot)
How to use Java enums (Enum) in MyBatis Mapper XML
How to dynamically switch JDK when building Java in Gradle
How to develop and register a Sota app in Java
How to simulate uploading a post-object form to OSS in Java
How to deploy Java application to Alibaba Cloud EDAS in Eclipse