@Jacksonized @Builder @Value 产生空 json
@Jacksonized @Builder @Value produce empty json
版本:
龙目岛:1.18.20
spring-引导:2.5.4
lombok.config(使用 IntelliJ 生成的默认值)
# add @lombok.Generated annotation to all Lombok generated methods
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
POJO
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();
}
}
当我运行这个设置时,MyRestController
收到一个空值apiRequest
。如果我取消注释控制器中注释掉的方法,则字符串化的 json 也为空。我在 Internet 上看到人们声称他们已经能够使用 @Jacksonized
序列化和反序列化不可变 POJO 的示例。
- 我做错了什么导致序列化失败吗?
- 假设序列化有效,那么我是否需要对
ApiResponse
进行一些特殊处理才能反序列化?
运行运行程序时的当前结果:
Received request: {"timestamp":null,"payload":{}}
注:
我已经看过这个讨论 。但我更倾向于@Jacksonized
工作。
更新 - 已解决
问题出在 Payload.java
POJO 上。如下修改 POJO 解决了问题:
@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;
}
}
正如@Jan Rike 所建议的,我将添加我的解决方案作为答案。
问题出在 Payload.java POJO 上。如下修改 POJO 解决了问题:
@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;
}
}
没有这个,Jackson 一直在寻找 getContent()
方法但失败了,因为它不存在(由于 @Getter(AccessLevel.NONE)
)
版本:
龙目岛:1.18.20 spring-引导:2.5.4
lombok.config(使用 IntelliJ 生成的默认值)
# add @lombok.Generated annotation to all Lombok generated methods
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
POJO
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();
}
}
当我运行这个设置时,MyRestController
收到一个空值apiRequest
。如果我取消注释控制器中注释掉的方法,则字符串化的 json 也为空。我在 Internet 上看到人们声称他们已经能够使用 @Jacksonized
序列化和反序列化不可变 POJO 的示例。
- 我做错了什么导致序列化失败吗?
- 假设序列化有效,那么我是否需要对
ApiResponse
进行一些特殊处理才能反序列化?
运行运行程序时的当前结果:
Received request: {"timestamp":null,"payload":{}}
注:
我已经看过这个讨论 @Jacksonized
工作。
更新 - 已解决
问题出在 Payload.java
POJO 上。如下修改 POJO 解决了问题:
@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;
}
}
正如@Jan Rike 所建议的,我将添加我的解决方案作为答案。
问题出在 Payload.java POJO 上。如下修改 POJO 解决了问题:
@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;
}
}
没有这个,Jackson 一直在寻找 getContent()
方法但失败了,因为它不存在(由于 @Getter(AccessLevel.NONE)
)