当前位置: 首页 > 知识库问答 >
问题:

未调用Jackson模块反序列化器

诸葛立果
2023-03-14

我正在尝试在SpringBoot应用程序中编写Jackson反序列化器模块。主要原因是使用自定义Jackson反序列化程序对传入请求中的pin码进行加密。加密属性由spring组件CipherInterface

我试图从这个解决方案,但我的自定义反序列化程序仍然没有调用。而不是基于此,始终调用StringDeserializer,并且不执行加密

提前谢谢

注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotation
public @interface Encrypted {
}

带有要加密字段的请求正文

@Value
public class CardCounterDecreaseRequest {
    @Encrypted
    private final String pinValue;
}

杰克逊构型

    @Bean
    ObjectMapper unrestrictObjectMapper(final CipherInterface cipherInterface) {
        return JsonMapper.builder()
                .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
                .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
                .enable(SerializationFeature.INDENT_OUTPUT)
                .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
                .enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)
                .disable(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY)
                .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
                .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                .disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT)
                .visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
                .visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
                .addModules(new EncryptionModule(cipherInterface), new JavaTimeModule(), new VavrModule(), new ParanamerModule())
                .build();
    }

模块:

public class EncryptionModule extends SimpleModule {

    private final CipherInterface cipher;


    public EncryptionModule(final CipherInterface cipher) {
        super();
        this.cipher = cipher;
    }

    @Override
    public void setupModule(final SetupContext context) {
        context.addBeanDeserializerModifier(new EncryptedDeserializerModifier(cipher));
    }

}

public class EncryptedDeserializerModifier extends BeanDeserializerModifier {

    private final CipherInterface cipher;

    public EncryptedDeserializerModifier(final CipherInterface cipher) {
        super();
        this.cipher = cipher;
    }

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

        final Iterator<SettableBeanProperty> it = builder.getProperties();

        while (it.hasNext()) {
            final SettableBeanProperty prop = it.next();
            if (null != prop.getAnnotation(Encrypted.class)) {
                final JsonDeserializer<Object> current = prop.getValueDeserializer(); // always  returns null
                final EncryptedJsonDeserializer encryptedDeserializer = new EncryptedJsonDeserializer(cipher, current);
                final SettableBeanProperty propWithEncryption = prop.withValueDeserializer(encryptedDeserializer);
                builder.addOrReplaceProperty(propWithEncryption, true);
            }
        }
        return builder;
    }

}

最后反序列化器:

public class EncryptedJsonDeserializer extends JsonDeserializer<Object> implements ContextualDeserializer {

    private final CipherInterface service;
    private final JsonDeserializer<Object> baseDeserializer;
    private final BeanProperty property;

    public EncryptedJsonDeserializer(final CipherInterface service, final JsonDeserializer<Object> baseDeserializer) {
        this.service = service;
        this.baseDeserializer = baseDeserializer;
        this.property = null;
    }

    public EncryptedJsonDeserializer(final CipherInterface service, final JsonDeserializer<Object> wrapped, final BeanProperty property) {
        this.service = service;
        this.baseDeserializer = wrapped;
        this.property = property;
    }

    @Override
    public Object deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonDeserializer<?> deserializer = baseDeserializer;
        if (deserializer instanceof ContextualDeserializer) {
            deserializer = ((ContextualDeserializer) deserializer).createContextual(ctxt, property);
        }
        return // encryption logic here
    }

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

共有1个答案

羊舌洛华
2023-03-14

只需尝试下面的代码,因为您已经正确地创建了反序列化程序,但并没有通知spring在反序列化此实体时使用下面的自定义deserializer类。添加这一额外的行@JsonDeserialize(使用=EncryptedJsonDeserializer.class),然后再试一次。

@Value
@JsonDeserialize(using = EncryptedJsonDeserializer.class)
public class CardCounterDecreaseRequest {
    @Encrypted
    private final String pinValue;
}

它会帮助你的。

 类似资料:
  • 我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif

  • 我有一个Spring项目,我尝试添加一个自定义反序列化器来反序列化日期属性,具体取决于它们的格式。如果我将其用作Date属性的注释,则效果很好。但是,如果我将反序列化器添加到对象映射器中,当Jackson反序列化日期时,它不会调用。 我尝试这样应用我的自定义反序列化程序: 我不想每次都对Date属性应用注释,我想默认使用此反序列化器。我做错了什么?

  • 添加到DTO对象后,我想向服务器发送一个列表 从…起 当向控制器发送对象时,它会抛出

  • 问题内容: 在Apache Jackson和Jackson一起使用Apache Jersey进行JSON序列化时(在服务器和客户端上),在反序列化通用List时遇到问题。 我正在生成的JSON如下,“数据”中的所有3个类都实现“ CheckStatusDetail”: 产生此JSON的对象如下所示,我在客户端使用相同的类: 自从我将此注释添加到我的CheckStatusDetail接口后,就应用了

  • 根据这里描述的内容,我应该使用JSR-310表示而不是数字表示来序列化对象。但是,我得到了数字表示。可能有什么问题? 我是这样配置我正在使用的映射器的: 这是我得到的反序列化示例 对于以下事例类:

  • 我在试着读我的。json文件。Is是一个车辆存储类。 这是错误: com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造的实例(尽管至少存在一个Creator):无法构造的实例(尽管至少存在一个Creator):没有字符串参数构造函数/工厂方法来从[Source:(File); line: 1,列: 1]处的字符串值反序列化