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

标签 java spring mongodb hibernate annotations

我是 Java 自定义注释的新手

I am developing a custom annotation which encrypt and decrypt a string and store it in database using spring and mongodb and for encryption I am using jasypt.

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

我的代码。

实体

public class Demo {

    @Id
    private Long id;

    private String somethingPublic;

    @EncryptDemo()
    private String somethingPrivate;

   //getter setter

}

自定义注释

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

}

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

我应该在哪里添加加密代码,以便在调用时反射(reflect)到我的注释中。

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

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

最佳答案

基本上你需要的是

  1. 创建一个 AbstractMongoEventListener 来监听 AfterConvertEventBeforeSaveEvent 事件
  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);
    }
}

加密回调:

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);
    }
}

解密回调:

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);
    }
}

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

@Bean
public EncryptionMongoEventListener encryptionMongoEventListener() {
    return new EncryptionMongoEventListener();
}

关于java - 如何使用自定义注释存储和加载加密值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31146221/

相关文章:

java - 下载文件时如何在 Springboot RestController 响应中返回 JSON 响应和文件的字节数组

java - 内存泄漏和性能是否足够?

java - 使用 jFreePanel 将年份添加到折线图上的 X 轴

java - 什么设置导致 ContextLoaderListener(根上下文)成为 DispatcherServlet 上下文上的 'parent' 上下文?

java - 获取 Spring Actuator 'health' 指标

java - 如何从Spring Boot连接在线MongoDB数据库?

java - 如何在 Android 上演奏非正弦音符?迷笛?

java - 在删除处理中处理临时实体。实体不被删除[解决]

node.js - 转换 Mongoose find 函数返回的数组的结果

MongoDB - 运行 setFeatureCompatibilityVersion 需要什么特权?