@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.