gpt4 book ai didi

java - 使用 Jackson 解码和反序列化其值为 Base64 编码、字符串化 JSON blob 的字段的最简单方法

转载 作者:太空宇宙 更新时间:2023-11-04 09:11:15 28 4
gpt4 key购买 nike

在我们的 Spring 数据项目中,我们使用“标准”方法来编写 DTO,其中我们使用 lombok 的 @Value@Builder 来实现不变性,并使用 @JsonDeserialize(builder = SomeClass.SomeClassBuilder.class) 来实现 jackson 反序列化。

这是一个最小的例子:

@RestController
class Controller {
@PostMapping("/post")
void post(@RequestBody PostBody body) {
System.out.println(body);
}
}

@Value
@Builder
@JsonDeserialize(builder = PostBody.PostBodyBuilder.class)
class PostBody {

byte[] id;

ClientData clientData;

@JsonPOJOBuilder(withPrefix = "")
public static class PostBodyBuilder {}
}

@Value
@Builder
@JsonDeserialize(builder = ClientData.ClientDataBuilder.class)
class ClientData {
String something;
Integer somethingElse;


@JsonPOJOBuilder(withPrefix = "")
public static class ClientDataBuilder {}
}

正如您所期望的那样,使用普通的 JSON 负载即可正常工作,例如:

{
"id": "c29tZWlk",
"clientData": {
"something": "somethingValue",
"somethingElse": 1
}
}

但是,我们有一个用例,其中 clientData 结构已知,但由于原因,它作为 Base64 编码的字符串化 JSON blob 发送,例如:

{
"id": "c29tZWlk",
"clientData": "eyJzb21ldGhpbmciOiJzb21ldGhpbmdWYWx1ZSIsInNvbWV0aGluZ0Vsc2UiOjF9"
}

如果我们能够在调用运行 ClientData 的反序列化器之前,作为 PostBody 反序列化的一部分,透明地解码和反字符串化该字段,那就太好了。

一种解决方案是为 PostBody 创建一个自定义反序列化器,但在实际示例中,还有更多字段需要手动处理。

我尝试创建自定义 ClientData 反序列化器,但我很难理解可用的各种不同类型的反序列化器接口(interface)。

到目前为止我已经得到了这样的东西:

@Value
@Builder
@JsonDeserialize(builder = PostBody.PostBodyBuilder.class)
class PostBody {

byte[] id;

@JsonDeserialize(using = ClientDataBase64Deserializer.class)
ClientData clientData;

@JsonPOJOBuilder(withPrefix = "")
public static class PostBodyBuilder {}
}

// SNIP

class ClientDataBase64Deserializer extends StdScalarDeserializer<ClientData> {

protected ClientDataBase64Deserializer() {
super(ClientData.class);
}

@Override
public ClientData deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
byte[] value = Base64.getDecoder().decode(jsonParser.getText());
System.out.println(new String(value)); // prints stringified JSON
jsonParser.setCurrentValue(/* somehow convert stringified JSON to a Tree Node? */ value);
return deserializationContext.readValue(jsonParser, ClientData.class);
}
}

如果您有任何有关如何继续此示例的想法,或者我可能缺少解决此问题的其他机制,我将不胜感激?

干杯

最佳答案

以真正的方式,我在提出问题后几分钟就设法解决了我的问题。

ClientDataBase64Deserializer 和 PostBody 的实现按预期工作:

@Value
@Builder
@JsonDeserialize(builder = PostBody.PostBodyBuilder.class)
public class PostBody {

byte[] id;

ClientData clientData;

public interface IPostBodyBuilder {
@JsonDeserialize(using = ClientDataBase64Deserializer.class)
PostBody.PostBodyBuilder clientData(ClientData clientData);
}

@JsonPOJOBuilder(withPrefix = "")
public static class PostBodyBuilder implements IPostBodyBuilder {}
}


class ClientDataBase64Deserializer extends StdScalarDeserializer<ClientData> {
private final ObjectMapper objectMapper;

protected ClientDataBase64Deserializer(ObjectMapper objectMapper) {
super(ClientData.class);
this.objectMapper = objectMapper;
}

@Override
public ClientData deserialize(
JsonParser jsonParser, DeserializationContext deserializationContext
) {
byte[] value = jsonParser.readValueAs(byte[].class);
return objectMapper.readValue(value, ClientData.class);
}
}

关于java - 使用 Jackson 解码和反序列化其值为 Base64 编码、字符串化 JSON blob 的字段的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59645093/

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