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

时间:2015-06-30 18:54:38

标签: java spring mongodb hibernate annotations

我是Java自定义注释的新手

  

我正在开发一个加密和解密字符串的自定义注释   使用spring和mongodb将其存储在数据库中,并使用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 {

}

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

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

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

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

1 个答案:

答案 0 :(得分:4)

基本上你需要的是

  1. 创建AbstractMongoEventListener以收听AfterConvertEventBeforeSaveEvent个活动
  2. 实施org.springframework.util.ReflectionUtils.FieldCallback回调以对这些事件采取行动
  3. 在Spring Data mongodb配置类
  4. 中将侦听器注册为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);
        }
    }
    

    Decrypt回调:

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