Hello @JsonAutoDetect

@JsonAutoDetect class annotation can be used to define which kinds of Methods are to be detected by auto-detection.

Auto-detection means using name conventions and/or signature templates to find methods to use for data binding. For example, so-called “getters” can be auto-detected by looking for public member methods that return a value, do not take argument, and have prefix “get” in their name.

Let’s code: –

The below classes are part of the one simple Spring Boot application.

public class Address {

    private String firstLine;
    private String secondLine;
    private String thirdLine;

    public Address(String firstLine, String secondLine, 
            String thirdLine) {
        this.firstLine = firstLine;
        this.secondLine = secondLine;
        this.thirdLine = thirdLine;
    }

    public String getFirstLine() {
        return firstLine;
    }

    public String getSecondLine() {
        return secondLine;
    }

    public String getThirdLine() {
        return thirdLine;
    }
}

public class Name {
    private String firstName;
    private String secondName;

    public Name(String firstName, String secondName) {
        this.firstName = firstName;
        this.secondName = secondName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getSecondName() {
        return secondName;
    }
}

public class Student {

    private Address address;
    private Name name;
    private Boolean isActive;

    public Student(Address address, Name name, 
           Boolean isActive) {
        this.address = address;
        this.name = name;
        this.isActive = isActive;
    }
    public Address getAddress() {
        return address;
    }

    public Name getName() {
        return name;
    }

    public Boolean getActive() {
        return isActive;
    }
}

and one rest controller

@RestController
public class MyController {

    @GetMapping("/student")
    public Student getStudent(){
        Address address = new Address("first", "second", "third");
        Name name = new Name("first Name" , "second name");
        Student student = new Student(address, name, Boolean.TRUE);
        return student;
    }
}

If you hit above rest api /student you will get response some thing like below JSON

{"address":{"firstLine":"first","secondLine":"second","thirdLine":"third"},"name":{"firstName":"first Name","secondName":"second name"},"active":true}

What if I tell you that there is no need to have those extra getters in Student and the same can be achieved with one simple annotation i.e. @JsonAutoDetect.

How? Let’s see below code

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Student {

    private Address address;
    private Name name;
    private Boolean isActive;

    public Student(Address address, Name name, Boolean isActive) {
        this.address = address;
        this.name = name;
        this.isActive = isActive;
    }
}

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) line is saying, any field of any visibility will be auto-detected.

Another use case, What if you want your JSON in below format i.e. no grouping in"address" and "name"

{"active":true,"secondName":"second name","firstLine":"first","secondLine":"second","thirdLine":"third","firstName":"first Name"}

All you have to do is replace your Employee class with

@JsonAutoDetect(
getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY) 
// Above line will search and auto detect for all the public getters only.
public class Student {

    private Address address;
    private Name name;
    private Boolean isActive;

    public Student(Address address, Name name, Boolean isActive) {
        this.address = address;
        this.name = name;
        this.isActive = isActive;
    }

    public String getFirstName() {
        return name.getFirstName();
    }

    public String getSecondName() {
        return name.getSecondName();
    }

    public String getFirstLine(){
        return address.getFirstLine();
    }

    public String getSecondLine(){
        return address.getSecondLine();
    }

    public String getThirdLine(){
        return address.getThirdLine();
    }

    public Boolean isActive() {
        return isActive;
    }
}

Another use case, what if you dont want “active” attribute in your response but want to keep the isActive() method in your Employee class for some calculation or anything. Just add below attribute in @JsonAutoDetect class annotation

isGetterVisibility = JsonAutoDetect.Visibility.NONE

The above line is ignoring all the method starting with is*

Another use case, What if you want "address" and "name" attributes in your response JSON but also wants to keep all the getters. Then update your @JsonAutoDetect annotation with below code

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE,
fieldVisibility = JsonAutoDetect.Visibility.ANY,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)

I am sure, there are lots of other conditions that you can use with @JsonAutoDetect based on your need. Below are all of the possible attributes and their possible values.

Following are the attributes of @JsonAutoDetect

Visibility LevelDescription
getterVisibilityMinimum visibility required for auto-detecting regular getter methods.
isGetterVisibilityMinimum visibility required for auto-detecting is-getter methods.
setterVisibilityMinimum visibility required for auto-detecting setter methods.
creatorVisibilityMinimum visibility required for auto-detecting Creator methods,except for no-argument constructors (which are always detected
no matter what)
fieldVisibilityMinimum visibility required for auto-detecting member fields.

There are few pre-defined Visibilities like below.

VisibilityDescription
DEFAULTValue that indicates that default visibility level (whatever it is,depends on context) is to be used. This usually means that inherited value (from parent visibility settings) is to be used.
NONEValue that indicates that no access modifiers are auto-detectable: this can be used to explicitly disable auto-detection for specifiedtypes
PUBLIC_ONLYValue to indicate that only ‘public’ access modifier is considered auto-detectable.
PROTECTED_AND_PUBLICValue that means access modifiers ‘protected’ and ‘public’ are auto-detectable (and ‘private’ and “package access” == no modifiers are not)
NON_PRIVATEValue that means that any other access modifier other than ‘private’ is considered auto-detectable
ANYValue that means that all kinds of access modifiers are acceptable, from private to public

You can play with above visibilities your self and the above code can be found in GitHub. 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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