Versions:
lombok: 1.18.20 spring-boot: 2.5.4
lombok.config (using default generated by IntelliJ)
# add @lombok.Generated annotation to all Lombok generated methods
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
POJOs
Payload.java
@Jacksonized @Builder @Value
public class Payload<T> {
@Getter(AccessLevel.NONE)
private T content;
/**
* @return payload content
*/
public T get() {
return content;
}
}
ApiRequest.java
@Jacksonized @Builder @Value
public class ApiRequest<T> {
private Date timestamp;
private Payload<T> payload;
}
Metadata.java
@Jacksonized @Builder(toBuilder = true) @Value
public class Metadata {
private String element;
private String threshold;
private String groupType;
private String groupId;
private String groupName;
private String groupPath;
private Instant from;
private Instant to;
}
MyRestController.java
@Slf4j
@Validated
@RestController
@RequestMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
@RequestScope
public class MyRestController {
@RequestMapping(
path = "/process",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ApiResponse process(@RequestBody ApiRequest<List<Metadata>> apiRequest) {
log.info("Received request: " + apiRequest);
return null; // Ignore for now
}
/*public ApiResponse process(@RequestBody String json) {
log.info("Received request: " + json);
return null; // Ignore for now
}*/
}
TestClass.class
public class TestClass {
public static void main(String[] args) throws Exception {
String fromStr = "2021-09-05T00:00:00Z";
String toStr = "2021-09-11T23:59:59Z";
Instant from = Instant.parse(fromStr);
Instant to = Instant.parse(toStr);
String groupName = "SomeGroupName";
String groupPath = "SomeGroupPath";
List<Metadata> metadataList = new ArrayList<>();
metadataList.add(Metadata.builder().element("e1").threshold("48").groupName(groupName).groupPath(groupPath).from(from).to(to).build());
metadataList.add(Metadata.builder().element("e2").threshold("35").groupName(groupName).groupPath(groupPath).from(from).to(to).build());
metadataList.add(Metadata.builder().element("e3").threshold("90").groupName(groupName).groupPath(groupPath).from(from).to(to).build());
Payload<List<Metadata>> payload = Payload.<List<Metadata>>builder().content(metadataList).build();
ApiRequest<List<Metadata>> apiRequest = ApiRequest.<List<Metadata>>builder().payload(payload).build();
RestTemplate rt = new RestTemplate();
final String baseUrl = "http://localhost:8080/test/process";
URI uri = new URI(baseUrl);
ResponseEntity<ApiResponse> response = rt.postForEntity(uri, apiRequest, ApiResponse.class);
ApiResponse r = response.getBody();
}
}
When I run this setup, the MyRestController
receives a null apiRequest
. If I uncomment the commented out method in the controller, the stringified json is also null. I saw examples on Internet where people claim that they have been able to use @Jacksonized
to serialize and deserialize immutable POJOs.
- Is there something wrong I am doing that is failing the serialization?
- Let's say the serialization works, then do I need some special handling for
ApiResponse
to get deserialized?
Current outcome when running the program:
Received request: {"timestamp":null,"payload":{}}
Note:
I already looked at this discussion here. But I am more inclined toward making @Jacksonized
work.
UPDATE - SOLVED
The problem was with the Payload.java
POJO. Modifying the POJO as below solved the problem:
@Jacksonized @Builder @Value
public class Payload<T> {
@Getter(AccessLevel.NONE)
private T content;
/**
* @return payload content
*/
@JsonProperty("content") // ADDED THIS TO TELL JACKSON TO USE THIS GETTER FOR content
public T get() {
return content;
}
}