@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 Level | Description |
getterVisibility | Minimum visibility required for auto-detecting regular getter methods. |
isGetterVisibility | Minimum visibility required for auto-detecting is-getter methods. |
setterVisibility | Minimum visibility required for auto-detecting setter methods. |
creatorVisibility | Minimum visibility required for auto-detecting Creator methods,except for no-argument constructors (which are always detected no matter what) |
fieldVisibility | Minimum visibility required for auto-detecting member fields. |
There are few pre-defined Visibilities like below.
Visibility | Description |
DEFAULT | Value 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. |
NONE | Value that indicates that no access modifiers are auto-detectable: this can be used to explicitly disable auto-detection for specifiedtypes |
PUBLIC_ONLY | Value to indicate that only ‘public’ access modifier is considered auto-detectable. |
PROTECTED_AND_PUBLIC | Value that means access modifiers ‘protected’ and ‘public’ are auto-detectable (and ‘private’ and “package access” == no modifiers are not) |
NON_PRIVATE | Value that means that any other access modifier other than ‘private’ is considered auto-detectable |
ANY | Value 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.