@Component("changeIdNoAopHandler")public classChangeIdNoAopHandler {private static Logger logger = LoggerFactory.getLogger(ChangeIdNoAopHandler.class);private static final String SECRET_KEY = "12345678"; //秘鑰
private String HANDLE_FIELD_NAME = "idNo"; //加密解密字段
private static final String ENCRYPT_FLAG = "encrypt"; //加密辨別 (判斷對值進行加密或者解密的操作)
private static final String DECRYPT_FLAG = "decrypt"; //解密辨別(判斷對值進行加密或者解密的操作)
@AutowiredprivateInetxValDualService netxValDualService;
@AutowiredprivateIThemisCryptoIdnoService themisCryptoIdnoService;
public Object parameterCheck(ProceedingJoinPoint joinPoint) throwsThrowable{
logger.info("開始執行aop方法修改參數。。。");
Object target= joinPoint.getTarget();//傳回被織入增強處理的目标對象 getThis:傳回AOP架構為目标對象生成的代理對象
Object[] args = joinPoint.getArgs(); //擷取目标對象方法參數//周遊參數 修改帶有idNo字段對象的值 (map list domain)
for(Object _obj : args) {try{
changValue(_obj,ENCRYPT_FLAG);//加密參數
}catch (Exception e) { //使用異常機制來驗證 _obj中 是否有idNo 字段
logger.error("修改目标方法參數字段值異常。目标類:"
+target.getClass()+"方法:"+joinPoint.getSignature().getName()+"修改的值:"+_obj,e);
}
}//執行方法,以新的參數(如果不帶args就是用原先的參數;這裡帶不帶都可以是,上面方法擷取原先參數的引用做的修改)
Object returnValue =joinPoint.proceed(args);//若未設定,則不需要解密
if(!ObjectIsNullUtil.isNullOrEmpty(returnValue)){try{//修改
returnValue = changValue(returnValue,DECRYPT_FLAG); //解密參數
}catch (Exception e) { //使用異常機制來驗證 _obj中 是否有idNo 字段
logger.error("修改目标方法傳回值異常。目标類:"
+target.getClass()+"方法:"+joinPoint.getSignature().getName()+"修改的值:"+returnValue,e);
}
}returnreturnValue;
}
private Object changValue(Object _obj, String flag) throwsException{//基本類型不作操作
if(_obj instanceofMap){
changeMapValue(_obj,flag);
}else if(_obj instanceofList){
@SuppressWarnings("unchecked")
List list = (List) _obj;for(Object obj : list) {if(obj instanceofMap){
changeMapValue(_obj,flag);
}else{
changObjectValue(_obj,flag);
}
}
}else{
changObjectValue(_obj,flag);
}return_obj;
}@SuppressWarnings("unchecked")private Object changeMapValue(Object _obj, String flag) throwsException{
Map map = (Map) _obj;if(map.containsKey(HANDLE_FIELD_NAME)){
Object fieldValue=map.get(HANDLE_FIELD_NAME);
String afterValue=crypto(fieldValue, flag);if(!ObjectIsNullUtil.isNullOrEmpty(afterValue)){
map.put(HANDLE_FIELD_NAME, afterValue);
}
}return_obj;
}
private Object changObjectValue(Object _obj, String flag) throwsException{
Class> resultClz =_obj.getClass();
Field[] fieldInfo= resultClz.getDeclaredFields(); //擷取class裡的所有字段 父類字段擷取不到 注:如果出現加密解密失敗 請先檢視idno是否在父類中
for(Field field : fieldInfo) {if(HANDLE_FIELD_NAME.equals(field.getName())){
field.setAccessible(true); //成員變量為private,故必須進行此操
Object fieldValue =field.get(_obj);
String afterValue=crypto(fieldValue, flag);if(!ObjectIsNullUtil.isNullOrEmpty(afterValue)){
field.set(_obj, afterValue);
}break;
}
}return_obj;
}
private String crypto(Object value,String flag) throwsException{if(ObjectIsNullUtil.isNullOrEmpty(value)){return null;
}//加密操作;加密之前先去查詢一下資料庫 有沒有 如果沒有 則insert
if(ENCRYPT_FLAG.equals(flag)) {
String encodeValue= Encryption.encode(SECRET_KEY, value.toString()); //加密
ThemisCryptoIdno idnoDomain = newThemisCryptoIdno();
idnoDomain.setCryptoIdno(encodeValue);
idnoDomain=themisCryptoIdnoService.selectOneByObject(idnoDomain);if(ObjectIsNullUtil.isNullOrEmpty(idnoDomain)){ //若空 則生成 seq 然後入庫 傳回seq
String tr_date =DateOperation.convertToDateStr2(DateOperation.currentTimeMills());//擷取有流水号
String inextValDual=netxValDualService.findIdNoSeq();//組流水:日期+ 7位流水 其他表儲存的就是這個idnoSeq
String idnoSeq=(tr_date+DateOperation.fill(inextValDual, '0', 7, true)).replaceAll("-", "");
idnoDomain= newThemisCryptoIdno();
idnoDomain.setOptTime(DateOperation.convertToDateStr1(DateOperation.currentTimeMills()));
idnoDomain.setCryptoIdno(encodeValue);
idnoDomain.setCryptoSeq(idnoSeq);
themisCryptoIdnoService.insert(idnoDomain);returnidnoSeq;
}else{ //不為空 直接傳回seq
returnidnoDomain.getCryptoSeq();
}
}else{ //解密操作 通過seq 查詢 然後解密傳回明文
ThemisCryptoIdno idnoDomain = newThemisCryptoIdno();
idnoDomain.setCryptoSeq(value.toString());
idnoDomain=themisCryptoIdnoService.selectOneByObject(idnoDomain);if(!ObjectIsNullUtil.isNullOrEmpty(idnoDomain)){return Encryption.decodeValue(SECRET_KEY, idnoDomain.getCryptoIdno()); //解密
}
}return null;
}public static void main(String[] args) throwsException {
System.out.println(Encryption.encode(SECRET_KEY,"142701197605091275"));
}
}