Java Jackson反序列化未在自定义反序列化程序上调用反序列化

Java Jackson反序列化未在自定义反序列化程序上调用反序列化,java,json,jackson,Java,Json,Jackson,我想反序列化窗体的类: public class TestFieldEncryptedMessage implements ITextMessage { @JsonProperty("text") @Encrypted(cipherAlias = "testAlias") private String text; public TestFieldEncryptedMessage() { } @JsonCreator public Te

我想反序列化窗体的类:

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实例之前取消对该值的加密

我采用的方法非常类似于:

也就是说,我正在构建一个扩展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后面的反序列化器被忽略

正如在上的许多其他示例(如此处)中所示,我使用以下设置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;
    }
}
公共类EncryptedDeserializerModifier扩展了BeanDeserializerModifier{
专用最终加密服务加密服务;
私有映射属性=新HashMap();
公共加密DeserializerModifier(最终加密服务EncryptionService){
this.encryptionService=encryptionService;
}
@凌驾
公共BeanDeserializerBuilder更新生成器(最终反序列化配置、最终BeanDescription BeanDescription、最终BeanDeserializerBuilder生成器){
Encrypted annotation=beanDescription.getType().getRawClass().getAnnotation(Encrypted.class);
迭代器it=builder.getProperties();
while(it.hasNext()){
SettableBeanProperty p=(SettableBeanProperty)it.next();
if(null!=p.getAnnotation(Encrypted.class)){
JsonDeserializer current=p.getValueDeserializer();
properties.put(p.getName(),p);
addOrReplaceProperty(p.withValueDeserializer(新的EncryptedJsonDeserializer(encryptionService,current,p)),true);
}
}
返回生成器;
}
}
最后,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);
}
@覆盖
公共对象反序列化(最终JsonParser解析器,最终反序列化上下文)引发JsonMappingException{
JsonDeserializer反序列化程序=baseDeserializer;
if(上下文序列化程序的反序列化程序实例){
反序列化程序=((ContextualDeserializer)反序列化程序).createContext(上下文,属性);
}
return service.decrypt(解析器、反序列化器、上下文、属性!=null?属性.getType():type);
}
@凌驾
公共JsonDeserializer CreateContextent(最终反序列化上下文,最终BeanProperty属性)引发JsonMappingException{
JsonDeserializer wrapped=context.findRootValueDeserializer(property.getType());
返回新的EncryptedJsonDeserializer(服务、包装、属性);
}
调用了createContext()方法,但未调用反序列化方法。整个执行过程中的属性始终是“text”属性,因此我似乎拥有正确的上下文

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


EDIT
实现ITextMessage
添加到解密的类中,我认为这是一个不重要的细节,但事实证明是问题的原因。

我发现了问题!如果仔细查看
TestFieldEncryptedMessage
类,它的
text
字段是加密的,您可以看到它实现了一个接口。使用接口是为了让消息为测试中的断言提供一些额外的工具,但是对于反序列化,会产生意外的结果。当ObjectMapper在json字符串中工作时,我认为它会尝试将反序列化程序与
ITextMessage
中的字段相匹配,而不是与
TestFieldEncryptedMessage
中的字段相匹配,这就是为什么没有调用自定义反序列化程序的原因(在
ITextMessage
中没有
text
字段)

一旦我停止实现ITextMessage,就会调用自定义反序列化程序