gpt4 book ai didi

java - Jackson JsonUnwrapped 和通用

转载 作者:行者123 更新时间:2023-12-02 11:07:05 27 4
gpt4 key购买 nike

我有两门课:

public class ResponseInfo {

private final int code;

private final String description;

@JsonCreator
public static ResponseInfo of(
@JsonProperty("code") int code,
@JsonProperty("description") String description
) {
return new ResponseInfo(code, description);
}

private ResponseInfo(
int code,
String description
) {
this.code = code;
this.description = description;
}

@JsonProperty("code")
public int code() {
return code;
}

@JsonProperty("description")
public String description() {
return description;
}
}

和:

 public class Response<T> {

private final ResponseInfo responseInfo;

private final T payload;

public static <T> Response<T> of(ResponseInfo responseInfo, T payload) {
return new Response<>(responseInfo, payload);
}

private Response(ResponseInfo responseInfo, T payload) {
this.responseInfo = responseInfo;
this.payload = payload;
}

@JsonUnwrapped
public ResponseInfo responseInfo() {
return responseInfo;
}

@JsonUnwrapped
public T payload() {
return payload;
}
}

我使用它们将附加信息添加到响应中(作为代码和描述)。例如:

Response.of(ResponseInfo.of(0, "OK"), User.of("Oleg", 23))

将被序列化为:

{
“年龄”:23,
“代码”:0,
“描述”:“好的”,
“姓名”:“奥列格”
}

Response的反序列化是如何完成的?

我无法直接在@JsonCreator中使用@JsonProperty,因为我不知道有效负载的属性。JsonCreator@JsonUnwrapped 也不起作用。

我正在使用jackson-datatype-jdk8:2.9.5

最佳答案

我已经创建了实现。

public class ResponseDeserializer
extends JsonDeserializer<Response<?>>
implements ContextualDeserializer {

private JavaType type;

@SuppressWarnings("unused")
public ResponseDeserializer() {
}

private ResponseDeserializer(JavaType type) {
this.type = type;
}

@Override
public JsonDeserializer<?> createContextual(
DeserializationContext context,
BeanProperty beanProperty
) {
JavaType contextualType = context.getContextualType();

if(contextualType == null) {
contextualType = beanProperty.getMember()
.getType();
}

if (!contextualType.isTypeOrSubTypeOf(Response.class)) {
throw new IllegalArgumentException("contextualType should be " + Response.class.getName());
}

final JavaType payloadType = contextualType.containedType(0);

return new ResponseDeserializer(payloadType);
}

@Override
public Response<?> deserialize(
JsonParser jsonParser,
DeserializationContext context
) throws IOException {
final ObjectCodec codec = jsonParser.getCodec();
JsonNode rootNode = codec.readTree(jsonParser);

final ResponseInfo responseInfo = ResponseInfo.of(
rootNode.get("code").asInt(),
rootNode.get("description").asText()
);

final JsonNode payloadNode = createPayloadNode(rootNode, codec);
final JsonParser payloadParser = payloadNode.traverse();

final Object payload = codec.readValue(payloadParser, type);
return Response.of(responseInfo, payload);
}

private JsonNode createPayloadNode(JsonNode rootNode, ObjectCodec codec) {
final Map<String, JsonNode> remainingNodes = findRemainingNodes(rootNode);

if(remainingNodes.size() == 1) {
final JsonNode payloadNode = remainingNodes.get("payload");

if(payloadNode != null && !payloadNode.isObject()) {
return payloadNode;
}
}

return buildRemainingNode(remainingNodes, codec);
}

private JsonNode buildRemainingNode(Map<String, JsonNode> remainingNodes, ObjectCodec codec) {
final ObjectNode remainingNode = (ObjectNode) codec.createObjectNode();
remainingNodes.forEach(remainingNode::set);
return remainingNode;
}

private Map<String, JsonNode> findRemainingNodes(JsonNode rootNode) {
Map<String, JsonNode> remainingNodes = new HashMap<>();

rootNode.fields()
.forEachRemaining(entry -> {
final String key = entry.getKey();

if(key.equals("code") || key.equals("description")) {
return;
}

remainingNodes.put(key, entry.getValue());
});

return remainingNodes;
}
}

关于java - Jackson JsonUnwrapped 和通用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50873921/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com