I am calling a third party REST endpoint. The request for the thrid party REST endpoint looks like this.
{
"body": {
"accountNumber": "12345"
},
"header": {
"username": "someusername",
"password": "somepassword"
}
}
I have created 3 bean classes
MyRequest.java
@Builder
@JsonDeserialize(builder = MyRequest.MyRequestBuilder.class)
public class MyRequest {
@JsonProperty("header")
private MyHeader header;
@JsonProperty("body")
private MyBody body;
}
MyBody.java
@Getter
@Builder
public class MyBody {
private String accountNumber;
}
MyHeader.java
@Getter
@Builder
public class MyHeader {
private String username;
private String password;
}
I'm creating request object using
MyBody body = MyBody.builder().accountNumber("12345").build();
MyHeader header = MyHeader.builder().username("someusername").password("somepassword").build();
MyRequest request = MyRequest.builder().body(body).header(header).build();
I'm calling the 3rd part REST endpoint using the below code
HttpEntity<MyRequest> httpEntity = new HttpEntity<>(myRequest, httpHeaders);
String url = "someurl";
someResponse = this.restTemplate.postForObject(url, httpEntity,
SomeResponse.class);
I'm getting proper response. But if I remove @Getter annotation from MyHeader and MyBody, 3rd party REST endpoint is getting null values in request. Why @Getter is necessary here. How to make this work without @Getter.
CodePudding user response:
if I remove
@Getter
annotation from MyHeader and MyBody, 3rd party REST endpoint is getting null values in request. Why@Getter
is necessary here. How to make this work without@Getter
.
You need to instruct Jackson somehow which data should be included during serialization. The default mechanism is to use getters for that purpose.
That's not the only way.
Alternatively, you can annotate certain fields with @JsonProperty
, or change the default visibility of the fields either globally or for a particular type using annotation @JsonAutoDetect
and set its property fieldVisibility
to ANY
(that would make the fields discoverable even in the absence of getters)
The key point is that the information on which data needs to be present in the serialized JSON should be provided somehow, and it doesn't matter how exactly.
Consider a dummy POJO with no getters:
@AllArgsConstructor
public class Foo {
@JsonProperty
private String bar;
}
Property bar
would be reflected in the resulting JSON.
ObjectMapper mapper = new ObjectMapper();
Foo foo = new Foo("baz");
String jsonFoo = mapper.writeValueAsString(foo);
System.out.println(jsonFoo);
Output:
{"bar":"baz"}
Now, if we remove @JsonProperty
(no getters as before) that's what would happen.
@AllArgsConstructor
public class Foo {
private String bar;
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
Foo foo = new Foo("baz");
String jsonFoo = mapper.writeValueAsString(foo);
System.out.println(jsonFoo);
Output:
{}
An empty Bean produces an empty JSON (or raises an exception, depending on configuration). And vise versa, Deserialization of an empty JSON gives an empty Bean.