如何使用自定义注释存储和加载加密值

Jim*_*mmy 4 java spring annotations hibernate mongodb

我是 Java 自定义注释新手

我正在开发一个自定义注释,它使用 spring 和 mongodb 加密和解密字符串并将其存储在数据库中,并且为了加密,我使用 jasypt。

我没有得到这样做的确切程序。

我的代码。

实体

public class Demo {

    @Id
    private Long id;

    private String somethingPublic;

    @EncryptDemo()
    private String somethingPrivate;

   //getter setter

}
Run Code Online (Sandbox Code Playgroud)

自定义注释

@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptDemo {

}
Run Code Online (Sandbox Code Playgroud)

在存储实体之前,如何将加密行为添加到自定义注释中。

我应该在哪里添加加密代码,以在调用时反映到我的注释中。

我想开发一个像hibernate一样的注释。

任何帮助将不胜感激。提前致谢。

小智 5

基本上你需要的是

  1. 创建一个AbstractMongoEventListener监听AfterConvertEvent事件BeforeSaveEvent
  2. 实现org.springframework.util.ReflectionUtils.FieldCallback回调以对这些事件执行操作
  3. 在 Spring Data mongodb 配置类中将侦听器注册为 Bean

听者:

public class EncryptionMongoEventListener extends AbstractMongoEventListener<Object> {
    @Override
    public void onBeforeSave(BeforeSaveEvent<Object> event) {
        Object source = event.getSource();
        DBObject dbObject = event.getDBObject();
        ReflectionUtils.doWithFields(source.getClass(), 
            new EncryptCallback(source, dbObject),
            ReflectionUtils.COPYABLE_FIELDS);
    }
    @Override
    public void onAfterConvert(AfterConvertEvent<Object> event) {
        Object source = event.getSource();
        ReflectionUtils.doWithFields(source.getClass(), 
            new DecryptCallback(source),
            ReflectionUtils.COPYABLE_FIELDS);
    }
}
Run Code Online (Sandbox Code Playgroud)

加密回调:

class EncryptCallback implements FieldCallback {
    private final Object source;
    private final DBObject dbObject;

    public EncryptCallback(final Object source, final DBObject dbObject) {
        this.source = source;
        this.dbObject = dbObject;
    }

    @Override
    public void doWith(Field field) 
        throws IllegalArgumentException, IllegalAccessException {
        if (!field.isAnnotationPresent(/* your annotation */.class)) {
            return;
        }
        ReflectionUtils.makeAccessible(field);
        String plainText = (String) ReflectionUtils.getField(field, source);
        String encryptedValue = /* your encryption of plainText */;
        // update the value in DBObject before it is saved to mongodb
        dbObject.put(field.getName(), encryptedValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

解密回调:

class DecryptCallback implements FieldCallback {
    private final Object source;

    public DecryptCallback(Object source) {
        this.source = source;
    }

    @Override
    public void doWith(Field field) 
        throws IllegalArgumentException, IllegalAccessException {
        if (!field.isAnnotationPresent(/* your annotation */.class)) {
            return;
        }
        ReflectionUtils.makeAccessible(field);
        String fieldValue = (String) ReflectionUtils.getField(field, source);
        String decryptedValue = /* your decryption of fieldValue */;
        // set the decrypted value in source Object
        ReflectionUtils.setField(field, source, decryptedValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,将侦听器注册为 Spring Data mongodb 配置类中的 bean

@Bean
public EncryptionMongoEventListener encryptionMongoEventListener() {
    return new EncryptionMongoEventListener();
}
Run Code Online (Sandbox Code Playgroud)