平时的项目中,总有这样或者那样的字段我们是要加密之后存进数据库的。
那么能否在写JavaBean的时候直接注明哪些是加密字段,提交数据库和从数据库返回时自动加解密呢。
为了清晰易懂我选择了用Java注解配合Spring来完成这件事情
首先我们看一个Demo
完整的Demo:DEMO
假设我们有很多很多的书要卖,有些书是已经有人预约一定要买的,有的没有,那么我们新建一个JavaBean
package com.liangyumingblog; public class Book { private String name; private String author; @EncryField(way = "I Get Encry") private String buyer; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getBuyer() { return buyer; } public void setBuyer(String buyer) { this.buyer = buyer; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", author='" + author + '\'' + ", buyer='" + buyer + '\'' + '}'; } }
这里有书的名字,作者,买家姓名,假设买家姓名是要加密保存的,那么我就在买家姓名上增加了一个EncryField注解。
光有注解可不行,接着我们还要为注解编写解释器:
package com.liangyumingblog; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import java.lang.reflect.Field; @Component @Aspect public class MyAnnotationProccesorImpl extends MyAnnotationProccesorAbstract implements Proccesor { @Override public void process(Object object) throws IllegalArgumentException, IllegalAccessException { this.setClazz(object); for (Field field : fields) { if (field.isAnnotationPresent(EncryField.class)) { if (!field.isAccessible()) { field.setAccessible(true); } EncryField getEncryWay = field.getAnnotation(EncryField.class); String EncryWay = getEncryWay.way(); field.set(object, EncryWay); } } } @Around("execution(* com.liangyumingblog.Printor.print(..))") public void join(ProceedingJoinPoint joinPoint) throws Throwable { this.process(joinPoint.getArgs()[0]); joinPoint.proceed(); } }
我们简单的对注解字段进行替换(实际开发中我们可以在这里做任何想要做的事情)。
接下来配置好Spring,AOP的配置。
我们看看测试的结果:
如此,这样我们的实际的逻辑代码中不用包含任何加解密的操作就可以完成了在写入数据库之前的加密。
PS:
import com.liangyumingblog.Printor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { String springXmlPath = "com/liangyumingblog/MyApplication.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(springXmlPath); Printor printor = ctx.getBean(Printor.class); System.out.println("UnCrypt " + ctx.getBean("HappyEnd")); printor.print(ctx.getBean("HappyEnd")); printor.print(ctx.getBean("banana")); } }
可以看到整个调用逻辑代码没有任何加密语句,对开发人员加解密就是透明的进行。