杰克逊反序列化不是在自定义解串器调用反序列化

迈克尔·考克森:

我想形式的反序列化类:

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如这里:我怎样才能包括使用杰克逊对象的原始JSON?,我成立了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没有找到合适的解串器?

编辑添加implements ITextMessage到解密类,我认为是一个不重要的细节,而且竟然是这个问题的原因。

迈克尔·考克森:

我发现这个问题!如果您在仔细观察TestFieldEncryptedMessage类,其text字段是加密的,你可以看到,它实现了一个接口。该接口用于以使这些信息提供一些额外的工具用于断言在测试中,但反序列化,有一个意想不到的后果。当ObjectMapper通过JSON字符串工作的方式,它会尝试,我想,解串器匹配到场内ITextMessage,而不是一个领域里面TestFieldEncryptedMessage,这就是为什么自定义解串器不叫(有没有text在现场ITextMessage)。

一旦我停止执行ITextMessage,自定义解串器被调用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章