gpt4 book ai didi

java - jackson 反序列化不在自定义反序列化器上调用反序列化

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:46:54 26 4
gpt4 key购买 nike

我想反序列化以下形式的类:

public class TestFieldEncryptedMessage implements ITextMessage {

@JsonProperty("text")
@Encrypted(cipherAlias = "testAlias")
private String text;

public TestFieldEncryptedMessage() {
}

@JsonCreator
public TestFieldEncryptedMessage(@JsonProperty("text") String text) {
this.text = text;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}
}

文本已加密,反序列化应在重建 TestFieldEncryptedMessage 实例之前取消加密该值。

我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto

也就是说,我正在构建一个扩展 SimpleModule 的模块:

public class CryptoModule extends SimpleModule {
public final static String GROUP_ID = "au.com.auspost.messaging";
public final static String ARTIFACT_ID = "jackson-json-crypto";
private EncryptedSerializerModifier serializerModifier;
private EncryptedDeserializerModifier deserializerModifier;

public CryptoModule() {
}

public CryptoModule addEncryptionService(final EncryptionService encryptionService) {
serializerModifier = new EncryptedSerializerModifier(encryptionService);
deserializerModifier = new EncryptedDeserializerModifier(encryptionService);
return this;
}

@Override
public String getModuleName() {
return ARTIFACT_ID;
}

@Override
public Version version() {
return new Version(major, minor, patch, null, GROUP_ID, ARTIFACT_ID);
}

@Override
public void setupModule(final SetupContext context) {
if ((null == serializerModifier) || (null == deserializerModifier))
throw new EncryptionException("Crypto module not initialised with an encryption service");
context.addBeanSerializerModifier(serializerModifier);
context.addBeanDeserializerModifier(deserializerModifier);
}
}

如您所见,设置了两个修饰符:EncryptedSerializerModifier 完美运行并由 ObjectMapper 调用,但忽略了 EncryptedDeserializerModifier 后面的反序列化器。

正如在 SO 上的许多其他示例中所见,例如:How can I include raw JSON in an object using Jackson? ,我设置了 EncryptedDeserializerModifier:

public class EncryptedDeserializerModifier extends BeanDeserializerModifier {

private final EncryptionService encryptionService;

private Map<String, SettableBeanProperty> properties = new HashMap<>();

public EncryptedDeserializerModifier(final EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}

@Override
public BeanDeserializerBuilder updateBuilder(final DeserializationConfig config, final BeanDescription beanDescription, final BeanDeserializerBuilder builder) {

Encrypted annotation = beanDescription.getType().getRawClass().getAnnotation(Encrypted.class);
Iterator it = builder.getProperties();

while (it.hasNext()) {
SettableBeanProperty p = (SettableBeanProperty) it.next();

if (null != p.getAnnotation(Encrypted.class)) {
JsonDeserializer<Object> current = p.getValueDeserializer();
properties.put(p.getName(), p);

builder.addOrReplaceProperty(p.withValueDeserializer(new EncryptedJsonDeserializer(encryptionService, current, p)), true);
}
}
return builder;
}
}

最后,EncryptedJsonDeserializer 本身会覆盖以下内容:

@Override
public Object deserialize(final JsonParser parser, final DeserializationContext context) throws JsonMappingException {
JsonDeserializer<?> deserializer = baseDeserializer;

if (deserializer instanceof ContextualDeserializer) {
deserializer = ((ContextualDeserializer) deserializer).createContextual(context, property);
}

return service.decrypt(parser, deserializer, context, property != null ? property.getType() : type);
}

@Override
public JsonDeserializer<?> createContextual(final DeserializationContext context, final BeanProperty property) throws JsonMappingException {
JsonDeserializer<?> wrapped = context.findRootValueDeserializer(property.getType());
return new EncryptedJsonDeserializer(service, wrapped, property);
}

调用了createContextual()方法,但没有调用反序列化方法。整个执行过程中的属性始终是“文本”属性,因此我似乎拥有正确的上下文。

有人知道为什么 ObjectMapper 找不到正确的反序列化器吗?

EDIT 添加了 implements ITextMessage 到解密类,我认为这是一个不重要的细节,但后来证明是问题的原因。

最佳答案

我找到问题了!如果你仔细观察 TestFieldEncryptedMessage 类,它的 text 字段是加密的,你可以看到它实现了一个接口(interface)。使用该接口(interface)以便消息为测试中的断言提供一些额外的工具,但是对于反序列化,会产生意想不到的后果。当 ObjectMapper 处理 json 字符串时,我认为它会尝试将反序列化器与 ITextMessage 中的字段匹配,而不是与 TestFieldEncryptedMessage 中的字段匹配,这这就是自定义解串器未被调用的原因(ITextMessage 中没有 text 字段)。

一旦我停止实现 ITextMessage,就会调用自定义解串器。

关于java - jackson 反序列化不在自定义反序列化器上调用反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51777405/

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