kafka-cndc-server | 修改 | 加解密开发,字段赋值不完整调整
mt 2024年12月17日18:19:26
Showing
20 changed files
with
544 additions
and
10 deletions
| ... | @@ -52,10 +52,10 @@ public class AttachmentUtil { | ... | @@ -52,10 +52,10 @@ public class AttachmentUtil { |
| 52 | private void initAttachment(Attachment attachment,String bizType,User user) throws Exception{ | 52 | private void initAttachment(Attachment attachment,String bizType,User user) throws Exception{ |
| 53 | DictionaryEntries attachmentBizTypeEntries = cacheSystem.getDicAttachmentBizType(bizType); | 53 | DictionaryEntries attachmentBizTypeEntries = cacheSystem.getDicAttachmentBizType(bizType); |
| 54 | attachment.setBizTypeCode(attachmentBizTypeEntries.getCode()); | 54 | attachment.setBizTypeCode(attachmentBizTypeEntries.getCode()); |
| 55 | - attachment.setBizTypeName(attachmentBizTypeEntries.getDescription()); | 55 | + attachment.setBizTypeName(attachmentBizTypeEntries.getEnglishName()); |
| 56 | DictionaryEntries attachmentFileTypeEntries = cacheSystem.getDicAttachmentFileType(AttachmentFileTypeEnum.FILE.getCode()); | 56 | DictionaryEntries attachmentFileTypeEntries = cacheSystem.getDicAttachmentFileType(AttachmentFileTypeEnum.FILE.getCode()); |
| 57 | attachment.setFileTypeCode(attachmentFileTypeEntries.getCode()); | 57 | attachment.setFileTypeCode(attachmentFileTypeEntries.getCode()); |
| 58 | - attachment.setFileTypeName(attachmentFileTypeEntries.getDescription()); | 58 | + attachment.setFileTypeName(attachmentFileTypeEntries.getEnglishName()); |
| 59 | attachment.setStatus(StatusEnum.YES.getCode()); | 59 | attachment.setStatus(StatusEnum.YES.getCode()); |
| 60 | attachment.setCreateUserId(user.getId()); | 60 | attachment.setCreateUserId(user.getId()); |
| 61 | attachment.setCreateUserName(user.getUserName()); | 61 | attachment.setCreateUserName(user.getUserName()); | ... | ... |
| ... | @@ -78,7 +78,7 @@ public class ConsignmentUtil { | ... | @@ -78,7 +78,7 @@ public class ConsignmentUtil { |
| 78 | consignment.setSubmitterId(user.getId()); | 78 | consignment.setSubmitterId(user.getId()); |
| 79 | //记录当前提交运单状态 | 79 | //记录当前提交运单状态 |
| 80 | consignment.setStatusCode(consignmentStatusDic.getCode()); | 80 | consignment.setStatusCode(consignmentStatusDic.getCode()); |
| 81 | - consignment.setStatusName(consignmentStatusDic.getDescription()); | 81 | + consignment.setStatusName(consignmentStatusDic.getEnglishName()); |
| 82 | /** | 82 | /** |
| 83 | * 初始化基础字段 | 83 | * 初始化基础字段 |
| 84 | */ | 84 | */ | ... | ... |
| ... | @@ -36,7 +36,7 @@ public class PushObUtil { | ... | @@ -36,7 +36,7 @@ public class PushObUtil { |
| 36 | pushOb.setConsignmentCode(consignment.getConsignmentCode()); | 36 | pushOb.setConsignmentCode(consignment.getConsignmentCode()); |
| 37 | pushOb.setPushNum(DigitConstants.DIGIT_ZERO_LONG); | 37 | pushOb.setPushNum(DigitConstants.DIGIT_ZERO_LONG); |
| 38 | pushOb.setStatusCode(pushObStatus.getCode()); | 38 | pushOb.setStatusCode(pushObStatus.getCode()); |
| 39 | - pushOb.setStatusName(pushObStatus.getDescription()); | 39 | + pushOb.setStatusName(pushObStatus.getEnglishName()); |
| 40 | pushOb.setCreateUserId(user.getId()); | 40 | pushOb.setCreateUserId(user.getId()); |
| 41 | pushOb.setCreateUserName(user.getUserName()); | 41 | pushOb.setCreateUserName(user.getUserName()); |
| 42 | pushOb.setModifyUserId(user.getId()); | 42 | pushOb.setModifyUserId(user.getId()); | ... | ... |
| ... | @@ -35,7 +35,7 @@ public class UploadRecordUtil { | ... | @@ -35,7 +35,7 @@ public class UploadRecordUtil { |
| 35 | uploadRecord.setConsignmentCode(consignmentCode); | 35 | uploadRecord.setConsignmentCode(consignmentCode); |
| 36 | //记录当前运单状态 | 36 | //记录当前运单状态 |
| 37 | uploadRecord.setStatusCode(consignmentStatusDic.getCode()); | 37 | uploadRecord.setStatusCode(consignmentStatusDic.getCode()); |
| 38 | - uploadRecord.setStatusName(consignmentStatusDic.getDescription()); | 38 | + uploadRecord.setStatusName(consignmentStatusDic.getEnglishName()); |
| 39 | /** | 39 | /** |
| 40 | * 初始化基础字段 | 40 | * 初始化基础字段 |
| 41 | */ | 41 | */ | ... | ... |
| 1 | +package com.fedex.connect.common.annotation; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.*; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * @Author mt | ||
| 7 | + * @Description 实体注解 | ||
| 8 | + * @Date 2024/12/17 | ||
| 9 | + */ | ||
| 10 | +@Target({ElementType.TYPE, ElementType.PARAMETER}) | ||
| 11 | +@Retention(RetentionPolicy.RUNTIME) | ||
| 12 | +@Inherited | ||
| 13 | +@Documented | ||
| 14 | +public @interface SensitiveEntity { | ||
| 15 | + | ||
| 16 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.fedex.connect.common.annotation; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.*; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * @Author mt | ||
| 7 | + * @Description 字段注解 | ||
| 8 | + * @Date 2024/12/17 | ||
| 9 | + */ | ||
| 10 | +@Target({ElementType.FIELD}) | ||
| 11 | +@Retention(RetentionPolicy.RUNTIME) | ||
| 12 | +@Inherited | ||
| 13 | +@Documented | ||
| 14 | +public @interface SensitiveField { | ||
| 15 | + | ||
| 16 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.fedex.connect.common.model.biz; | 1 | package com.fedex.connect.common.model.biz; |
| 2 | 2 | ||
| 3 | +import com.fedex.connect.common.annotation.SensitiveEntity; | ||
| 4 | +import com.fedex.connect.common.annotation.SensitiveField; | ||
| 5 | + | ||
| 3 | import java.io.Serializable; | 6 | import java.io.Serializable; |
| 4 | import java.math.BigDecimal; | 7 | import java.math.BigDecimal; |
| 5 | import java.util.Date; | 8 | import java.util.Date; |
| 6 | 9 | ||
| 7 | /** | 10 | /** |
| 8 | - * DESC: CE501报文业务表 | 11 | + * DESC: CE501报文业务表,增加需要加密标志 |
| 9 | * TABLE: ICLEARIMP.T_BIZ_CE_INFO | 12 | * TABLE: ICLEARIMP.T_BIZ_CE_INFO |
| 10 | */ | 13 | */ |
| 14 | +@SensitiveEntity | ||
| 11 | public class CeInfo implements Serializable { | 15 | public class CeInfo implements Serializable { |
| 12 | /** | 16 | /** |
| 13 | * ID,自动增加 | 17 | * ID,自动增加 |
| ... | @@ -92,11 +96,13 @@ public class CeInfo implements Serializable { | ... | @@ -92,11 +96,13 @@ public class CeInfo implements Serializable { |
| 92 | /** | 96 | /** |
| 93 | * 发货联系人姓名 | 97 | * 发货联系人姓名 |
| 94 | */ | 98 | */ |
| 99 | + @SensitiveField | ||
| 95 | private String shipperContactName; | 100 | private String shipperContactName; |
| 96 | 101 | ||
| 97 | /** | 102 | /** |
| 98 | * 发货人手机号 | 103 | * 发货人手机号 |
| 99 | */ | 104 | */ |
| 105 | + @SensitiveField | ||
| 100 | private String shipperPhone; | 106 | private String shipperPhone; |
| 101 | 107 | ||
| 102 | /** | 108 | /** | ... | ... |
| 1 | package com.fedex.connect.common.model.biz; | 1 | package com.fedex.connect.common.model.biz; |
| 2 | 2 | ||
| 3 | +import com.fedex.connect.common.annotation.SensitiveEntity; | ||
| 4 | +import com.fedex.connect.common.annotation.SensitiveField; | ||
| 5 | + | ||
| 3 | import java.io.Serializable; | 6 | import java.io.Serializable; |
| 4 | import java.math.BigDecimal; | 7 | import java.math.BigDecimal; |
| 5 | import java.util.Date; | 8 | import java.util.Date; |
| ... | @@ -8,6 +11,7 @@ import java.util.Date; | ... | @@ -8,6 +11,7 @@ import java.util.Date; |
| 8 | * DESC: 运单表 | 11 | * DESC: 运单表 |
| 9 | * TABLE: T_BIZ_CONSIGNMENT | 12 | * TABLE: T_BIZ_CONSIGNMENT |
| 10 | */ | 13 | */ |
| 14 | +@SensitiveEntity | ||
| 11 | public class Consignment implements Serializable { | 15 | public class Consignment implements Serializable { |
| 12 | /** | 16 | /** |
| 13 | * ID,自动增加 | 17 | * ID,自动增加 |
| ... | @@ -67,11 +71,13 @@ public class Consignment implements Serializable { | ... | @@ -67,11 +71,13 @@ public class Consignment implements Serializable { |
| 67 | /** | 71 | /** |
| 68 | * 发货联系人姓名 | 72 | * 发货联系人姓名 |
| 69 | */ | 73 | */ |
| 74 | + @SensitiveField | ||
| 70 | private String shipperContactName; | 75 | private String shipperContactName; |
| 71 | 76 | ||
| 72 | /** | 77 | /** |
| 73 | * 发货人手机号 | 78 | * 发货人手机号 |
| 74 | */ | 79 | */ |
| 80 | + @SensitiveField | ||
| 75 | private String shipperPhone; | 81 | private String shipperPhone; |
| 76 | 82 | ||
| 77 | /** | 83 | /** | ... | ... |
| 1 | package com.fedex.connect.common.model.sys; | 1 | package com.fedex.connect.common.model.sys; |
| 2 | 2 | ||
| 3 | +import com.fedex.connect.common.annotation.SensitiveEntity; | ||
| 4 | +import com.fedex.connect.common.annotation.SensitiveField; | ||
| 5 | + | ||
| 3 | import java.io.Serializable; | 6 | import java.io.Serializable; |
| 4 | import java.util.Date; | 7 | import java.util.Date; |
| 5 | 8 | ||
| ... | @@ -7,6 +10,7 @@ import java.util.Date; | ... | @@ -7,6 +10,7 @@ import java.util.Date; |
| 7 | * DESC: 用户表 | 10 | * DESC: 用户表 |
| 8 | * TABLE: ICLEARIMP.T_SYS_USER | 11 | * TABLE: ICLEARIMP.T_SYS_USER |
| 9 | */ | 12 | */ |
| 13 | +@SensitiveEntity | ||
| 10 | public class User implements Serializable { | 14 | public class User implements Serializable { |
| 11 | /** | 15 | /** |
| 12 | * ID,主键自增 | 16 | * ID,主键自增 |
| ... | @@ -21,6 +25,7 @@ public class User implements Serializable { | ... | @@ -21,6 +25,7 @@ public class User implements Serializable { |
| 21 | /** | 25 | /** |
| 22 | * 用户姓名 | 26 | * 用户姓名 |
| 23 | */ | 27 | */ |
| 28 | + @SensitiveField | ||
| 24 | private String userName; | 29 | private String userName; |
| 25 | 30 | ||
| 26 | /** | 31 | /** |
| ... | @@ -41,6 +46,7 @@ public class User implements Serializable { | ... | @@ -41,6 +46,7 @@ public class User implements Serializable { |
| 41 | /** | 46 | /** |
| 42 | * 联系电话 | 47 | * 联系电话 |
| 43 | */ | 48 | */ |
| 49 | + @SensitiveField | ||
| 44 | private String phone; | 50 | private String phone; |
| 45 | 51 | ||
| 46 | /** | 52 | /** | ... | ... |
| 1 | +package com.fedex.connect.common.dependencies.interceptor; | ||
| 2 | + | ||
| 3 | +import com.fedex.connect.common.annotation.SensitiveEntity; | ||
| 4 | +import com.fedex.connect.common.dependencies.service.sys.IAesService; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.apache.ibatis.binding.MapperMethod; | ||
| 7 | +import org.apache.ibatis.executor.parameter.ParameterHandler; | ||
| 8 | +import org.apache.ibatis.executor.resultset.ResultSetHandler; | ||
| 9 | +import org.apache.ibatis.executor.statement.StatementHandler; | ||
| 10 | +import org.apache.ibatis.mapping.BoundSql; | ||
| 11 | +import org.apache.ibatis.plugin.*; | ||
| 12 | +import org.springframework.core.annotation.AnnotationUtils; | ||
| 13 | +import org.springframework.stereotype.Component; | ||
| 14 | +import org.springframework.util.CollectionUtils; | ||
| 15 | + | ||
| 16 | +import javax.annotation.Resource; | ||
| 17 | +import java.lang.reflect.Field; | ||
| 18 | +import java.sql.Connection; | ||
| 19 | +import java.sql.PreparedStatement; | ||
| 20 | +import java.sql.Statement; | ||
| 21 | +import java.util.ArrayList; | ||
| 22 | +import java.util.Objects; | ||
| 23 | +import java.util.Properties; | ||
| 24 | + | ||
| 25 | +@Component | ||
| 26 | +@Intercepts({ | ||
| 27 | + @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}), | ||
| 28 | + @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class), | ||
| 29 | + @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) | ||
| 30 | +}) | ||
| 31 | +@Slf4j | ||
| 32 | +public class MyBatisInterceptor implements Interceptor { | ||
| 33 | + @Resource | ||
| 34 | + private IAesService aesService; | ||
| 35 | + | ||
| 36 | + @Override | ||
| 37 | + public Object intercept(Invocation invocation) throws Throwable { | ||
| 38 | + Object target = invocation.getTarget(); | ||
| 39 | + //拦截sql结果处理器 | ||
| 40 | + if (target instanceof ResultSetHandler) { | ||
| 41 | + return resultDecrypt(invocation); | ||
| 42 | + } | ||
| 43 | + //拦截sql参数处理器 | ||
| 44 | + if (target instanceof ParameterHandler) { | ||
| 45 | + return parameterEncrypt(invocation); | ||
| 46 | + } | ||
| 47 | + //拦截sql语句处理器 | ||
| 48 | + if (target instanceof StatementHandler) { | ||
| 49 | + return replaceSql(invocation); | ||
| 50 | + } | ||
| 51 | + return invocation.proceed(); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 对mybatis映射结果进行字段解密 | ||
| 56 | + * | ||
| 57 | + * @param invocation 参数 | ||
| 58 | + * @return 结果 | ||
| 59 | + * @throws Throwable 异常 | ||
| 60 | + */ | ||
| 61 | + private Object resultDecrypt(Invocation invocation) throws Throwable { | ||
| 62 | + //取出查询的结果 | ||
| 63 | + Object resultObject = invocation.proceed(); | ||
| 64 | + if (Objects.isNull(resultObject)) { | ||
| 65 | + return null; | ||
| 66 | + } | ||
| 67 | + //基于selectList | ||
| 68 | + if (resultObject instanceof ArrayList) { | ||
| 69 | + ArrayList resultList = (ArrayList) resultObject; | ||
| 70 | + if (CollectionUtils.isEmpty(resultList)) { | ||
| 71 | + return resultObject; | ||
| 72 | + } | ||
| 73 | + for (Object result : resultList) { | ||
| 74 | + if (needToDecrypt(result)) { | ||
| 75 | + //逐一解密 | ||
| 76 | + aesService.decrypt(result); | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + //基于selectOne | ||
| 80 | + } else { | ||
| 81 | + if (needToDecrypt(resultObject)) { | ||
| 82 | + aesService.decrypt(resultObject); | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + return resultObject; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + /** | ||
| 89 | + * mybatis映射参数进行加密 | ||
| 90 | + * | ||
| 91 | + * @param invocation 参数 | ||
| 92 | + * @return 结果 | ||
| 93 | + * @throws Throwable 异常 | ||
| 94 | + */ | ||
| 95 | + private Object parameterEncrypt(Invocation invocation) throws Throwable { | ||
| 96 | + //@Signature 指定了 type= parameterHandler 后,这里的 invocation.getTarget() 便是parameterHandler | ||
| 97 | + //若指定ResultSetHandler ,这里则能强转为ResultSetHandler | ||
| 98 | + ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget(); | ||
| 99 | + // 获取参数对像,即 mapper 中 paramsType 的实例 | ||
| 100 | + Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject"); | ||
| 101 | + parameterField.setAccessible(true); | ||
| 102 | + //取出实例 | ||
| 103 | + Object parameterObject = parameterField.get(parameterHandler); | ||
| 104 | + | ||
| 105 | + if(parameterHandler.getParameterObject() instanceof MapperMethod.ParamMap){ | ||
| 106 | + MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) parameterHandler.getParameterObject(); | ||
| 107 | + parameterObject = paramMap.get("param1"); | ||
| 108 | + } | ||
| 109 | + if (null == parameterObject) { | ||
| 110 | + return invocation.proceed(); | ||
| 111 | + } | ||
| 112 | + Class<?> parameterObjectClass = parameterObject.getClass(); | ||
| 113 | + //校验该实例的类是否被@SensitiveEntity所注解 | ||
| 114 | + SensitiveEntity sensitiveEntity = AnnotationUtils.findAnnotation(parameterObjectClass, SensitiveEntity.class); | ||
| 115 | + //未被@SensitiveEntity所注解 则为null | ||
| 116 | + if (Objects.isNull(sensitiveEntity)) { | ||
| 117 | + return invocation.proceed(); | ||
| 118 | + } | ||
| 119 | + //取出当前当前类所有字段,传入加密方法 | ||
| 120 | + Field[] allFields = parameterObjectClass.getDeclaredFields(); | ||
| 121 | + aesService.encrypt(allFields, parameterObject); | ||
| 122 | + return invocation.proceed(); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + * 替换mybatis Sql中的加密Key | ||
| 127 | + * | ||
| 128 | + * @param invocation 参数 | ||
| 129 | + * @return 结果 | ||
| 130 | + * @throws Throwable 异常 | ||
| 131 | + */ | ||
| 132 | + private Object replaceSql(Invocation invocation) throws Throwable { | ||
| 133 | + StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); | ||
| 134 | + BoundSql boundSql = statementHandler.getBoundSql(); | ||
| 135 | + //获取到原始sql语句 | ||
| 136 | + String sql = boundSql.getSql(); | ||
| 137 | + if (null == sql){ | ||
| 138 | + return invocation.proceed(); | ||
| 139 | + } | ||
| 140 | + //通过反射修改sql语句 | ||
| 141 | + Field field = boundSql.getClass().getDeclaredField("sql"); | ||
| 142 | + field.setAccessible(true); | ||
| 143 | + field.set(boundSql, sql); | ||
| 144 | + return invocation.proceed(); | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + /** | ||
| 148 | + * 判断是否包含需要加解密对象 | ||
| 149 | + * | ||
| 150 | + * @param object 参数 | ||
| 151 | + * @return 结果 | ||
| 152 | + */ | ||
| 153 | + private boolean needToDecrypt(Object object) { | ||
| 154 | + if(Objects.isNull(object)){ | ||
| 155 | + return false; | ||
| 156 | + } | ||
| 157 | + Class<?> objectClass = object.getClass(); | ||
| 158 | + Class<?> parentClass = objectClass.getSuperclass(); | ||
| 159 | + SensitiveEntity sensitiveEntity = AnnotationUtils.findAnnotation(objectClass, SensitiveEntity.class); | ||
| 160 | + SensitiveEntity parentSensitiveEntity = AnnotationUtils.findAnnotation(parentClass, SensitiveEntity.class); | ||
| 161 | + | ||
| 162 | + return Objects.nonNull(sensitiveEntity) || Objects.nonNull(parentSensitiveEntity); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + @Override | ||
| 166 | + public Object plugin(Object target) { | ||
| 167 | + return Plugin.wrap(target, this); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + @Override | ||
| 171 | + public void setProperties(Properties properties) { | ||
| 172 | + | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | +} |
| 1 | +package com.fedex.connect.common.dependencies.service.sys.impl; | ||
| 2 | + | ||
| 3 | +import com.fedex.connect.common.annotation.SensitiveField; | ||
| 4 | +import com.fedex.connect.common.dependencies.service.sys.IAesService; | ||
| 5 | +import com.fedex.connect.common.dependencies.util.arithmetic.AesFieldUtils; | ||
| 6 | +import org.apache.commons.lang3.StringUtils; | ||
| 7 | +import org.springframework.stereotype.Service; | ||
| 8 | + | ||
| 9 | +import javax.annotation.Resource; | ||
| 10 | +import java.lang.reflect.Field; | ||
| 11 | +import java.util.Objects; | ||
| 12 | + | ||
| 13 | +@Service | ||
| 14 | +public class AesServiceImpl implements IAesService { | ||
| 15 | + @Resource | ||
| 16 | + private AesFieldUtils aesFieldUtils; | ||
| 17 | + | ||
| 18 | + @Override | ||
| 19 | + public <T> T encrypt(Field[] declaredFields, T paramsObject) throws Exception { | ||
| 20 | + for (Field field : declaredFields) { | ||
| 21 | + //取出所有被EncryptDecryptField注解的字段 | ||
| 22 | + SensitiveField sensitiveField = field.getAnnotation(SensitiveField.class); | ||
| 23 | + if (Objects.isNull(sensitiveField)) { | ||
| 24 | + continue; | ||
| 25 | + } | ||
| 26 | + field.setAccessible(true); | ||
| 27 | + Object object = field.get(paramsObject); | ||
| 28 | + //暂时只实现String类型的加密 | ||
| 29 | + if (object instanceof String) { | ||
| 30 | + String value = (String) object; | ||
| 31 | + //如果映射字段值为空,并且以==结尾则跳过不进行加密 | ||
| 32 | + if (StringUtils.isEmpty(value) || aesFieldUtils.isBase64(value)) { | ||
| 33 | + continue; | ||
| 34 | + } | ||
| 35 | + //加密 这里我使用自定义的AES加密工具 | ||
| 36 | + field.set(paramsObject, aesFieldUtils.encrypt(value)); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return paramsObject; | ||
| 40 | + | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public <T> T decrypt(T result) throws Exception { | ||
| 45 | + //取出resultType的类 | ||
| 46 | + Class<?> resultClass = result.getClass(); | ||
| 47 | + Field[] allFields = resultClass.getDeclaredFields(); | ||
| 48 | + for (Field field : allFields) { | ||
| 49 | + //取出所有被EncryptDecryptField注解的字段 | ||
| 50 | + SensitiveField sensitiveField = field.getAnnotation(SensitiveField.class); | ||
| 51 | + if (Objects.isNull(sensitiveField)) { | ||
| 52 | + continue; | ||
| 53 | + } | ||
| 54 | + field.setAccessible(true); | ||
| 55 | + Object object = field.get(result); | ||
| 56 | + //只支持String的解密 | ||
| 57 | + if (object instanceof String) { | ||
| 58 | + String value = (String) object; | ||
| 59 | + //如果映射字段值为空,并且不已==结尾则跳过不进行解密 | ||
| 60 | + if (StringUtils.isBlank(value) || !aesFieldUtils.isBase64(value)) { | ||
| 61 | + continue; | ||
| 62 | + } | ||
| 63 | + //对注解的字段进行逐一解密 | ||
| 64 | + field.set(result, aesFieldUtils.decrypt(value)); | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + return result; | ||
| 68 | + } | ||
| 69 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.fedex.connect.common.dependencies.util.arithmetic; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 密钥的长度 | ||
| 5 | + */ | ||
| 6 | +public enum AESType { | ||
| 7 | + AES_128(128), | ||
| 8 | + AES_192(192), | ||
| 9 | + AES_256(256); | ||
| 10 | + | ||
| 11 | + public int value; | ||
| 12 | + | ||
| 13 | + private AESType(int value) { | ||
| 14 | + this.value = value; | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + public int getValue() { | ||
| 18 | + return value; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + public void setValue(int value) { | ||
| 22 | + this.value = value; | ||
| 23 | + } | ||
| 24 | +} |
This diff is collapsed. Click to expand it.
| 1 | +package com.fedex.connect.common.dependencies.util.arithmetic; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.springframework.stereotype.Component; | ||
| 6 | +import org.springframework.util.Base64Utils; | ||
| 7 | + | ||
| 8 | +import javax.crypto.Cipher; | ||
| 9 | +import javax.crypto.spec.SecretKeySpec; | ||
| 10 | +import java.util.regex.Matcher; | ||
| 11 | +import java.util.regex.Pattern; | ||
| 12 | + | ||
| 13 | +@Slf4j | ||
| 14 | +@Component | ||
| 15 | +public class AesFieldUtils { | ||
| 16 | + /** | ||
| 17 | + * 加密算法 | ||
| 18 | + */ | ||
| 19 | + private final String KEY_ALGORITHM = "AES"; | ||
| 20 | + /** | ||
| 21 | + * 算法/模式/补码方式 | ||
| 22 | + */ | ||
| 23 | + private final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; | ||
| 24 | + /** | ||
| 25 | + * 编码格式 | ||
| 26 | + */ | ||
| 27 | + private final String CODE = "utf-8"; | ||
| 28 | + /** | ||
| 29 | + * base64验证规则 | ||
| 30 | + */ | ||
| 31 | + private static final String BASE64_RULE = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)=?$"; | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 正则验证对象 | ||
| 35 | + */ | ||
| 36 | + private static final Pattern PATTERN = Pattern.compile(BASE64_RULE); | ||
| 37 | + /** | ||
| 38 | + * 加解密 密钥key | ||
| 39 | + */ | ||
| 40 | + private String key = "f9c338063a04b7cedf2c09ec93119e8c"; | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * @param content 加密字符串 | ||
| 44 | + * @return 加密结果 | ||
| 45 | + */ | ||
| 46 | + public String encrypt(String content) { | ||
| 47 | + return encrypt(content, key); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * 加密 | ||
| 52 | + * | ||
| 53 | + * @param content 加密参数 | ||
| 54 | + * @param key 加密key | ||
| 55 | + * @return 结果字符串 | ||
| 56 | + */ | ||
| 57 | + public String encrypt(String content, String key) { | ||
| 58 | + //判断如果已经是base64加密字符串则返回原字符串 | ||
| 59 | + if (isBase64(content)) { | ||
| 60 | + return content; | ||
| 61 | + } | ||
| 62 | + // 为了安全起见,暂时不加密,需要时再放开 | ||
| 63 | + //return content; | ||
| 64 | + byte[] encrypted = encrypt2bytes(content, key); | ||
| 65 | + if (null == encrypted || encrypted.length < 1) { | ||
| 66 | + log.error("加密字符串[{}]转字节为null", content); | ||
| 67 | + return null; | ||
| 68 | + } | ||
| 69 | + return Base64Utils.encodeToString(encrypted); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * @param content 加密字符串 | ||
| 74 | + * @param key 加密key | ||
| 75 | + * @return 返回加密字节 | ||
| 76 | + */ | ||
| 77 | + public byte[] encrypt2bytes(String content, String key) { | ||
| 78 | + try { | ||
| 79 | + byte[] raw = key.getBytes(CODE); | ||
| 80 | + SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM); | ||
| 81 | + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); | ||
| 82 | + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); | ||
| 83 | + return cipher.doFinal(content.getBytes(CODE)); | ||
| 84 | + } catch (Exception e) { | ||
| 85 | + log.error("failed to encrypt: {} of {}", content, e); | ||
| 86 | + return null; | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + * @param content 加密字符串 | ||
| 92 | + * @return 返回加密结果 | ||
| 93 | + */ | ||
| 94 | + public String decrypt(String content) { | ||
| 95 | + try { | ||
| 96 | + return decrypt(content, key); | ||
| 97 | + } catch (Exception e) { | ||
| 98 | + log.error("failed to decrypt: {}, e: {}", content, e); | ||
| 99 | + return null; | ||
| 100 | + } | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + /** | ||
| 104 | + * 解密 | ||
| 105 | + * | ||
| 106 | + * @param content 解密字符串 | ||
| 107 | + * @param key 解密key | ||
| 108 | + * @return 解密结果 | ||
| 109 | + */ | ||
| 110 | + public String decrypt(String content, String key) throws Exception { | ||
| 111 | + //不是base64格式字符串则不进行解密 | ||
| 112 | + if (!isBase64(content)) { | ||
| 113 | + return content; | ||
| 114 | + } | ||
| 115 | + // 为了安全起见,暂时不加密解密,需要时再放开 | ||
| 116 | + //return content; | ||
| 117 | + return decrypt(Base64Utils.decodeFromString(content), key); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + /** | ||
| 121 | + * @param content 解密字节 | ||
| 122 | + * @param key 解密key | ||
| 123 | + * @return 返回解密内容 | ||
| 124 | + */ | ||
| 125 | + public String decrypt(byte[] content, String key) throws Exception { | ||
| 126 | + if (key == null) { | ||
| 127 | + log.error("AES key should not be null"); | ||
| 128 | + return null; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + byte[] raw = key.getBytes(CODE); | ||
| 132 | + SecretKeySpec keySpec = new SecretKeySpec(raw, KEY_ALGORITHM); | ||
| 133 | + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); | ||
| 134 | + cipher.init(Cipher.DECRYPT_MODE, keySpec); | ||
| 135 | + try { | ||
| 136 | + byte[] original = cipher.doFinal(content); | ||
| 137 | + return new String(original, CODE); | ||
| 138 | + } catch (Exception e) { | ||
| 139 | + log.error("failed to decrypt content: {}/ key: {}, e: {}", content, key, e); | ||
| 140 | + return null; | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + /** | ||
| 145 | + * 判断是否为 base64加密 | ||
| 146 | + * | ||
| 147 | + * @param str 参数 | ||
| 148 | + * @return 结果 | ||
| 149 | + */ | ||
| 150 | + public static boolean isBase64(String str) { | ||
| 151 | + Matcher matcher = PATTERN.matcher(str); | ||
| 152 | + return matcher.matches(); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | +} |
| 1 | +package com.fedex.connect.common.dependencies.util.arithmetic; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * | ||
| 5 | + */ | ||
| 6 | +public class EncodeType { | ||
| 7 | + /** | ||
| 8 | + 算法/模式/填充 字节加密后数据长度 不满16字节加密后长度 | ||
| 9 | + AES/CBC/NoPadding 16 不支持 | ||
| 10 | + AES/CBC/PKCS5Padding 32 16 | ||
| 11 | + AES/CBC/ISO10126Padding 32 16 | ||
| 12 | + AES/CFB/NoPadding 16 原始数据长度 | ||
| 13 | + AES/CFB/PKCS5Padding 32 16 | ||
| 14 | + AES/CFB/ISO10126Padding 32 16 | ||
| 15 | + AES/ECB/NoPadding 16 不支持 | ||
| 16 | + AES/ECB/PKCS5Padding 32 16 | ||
| 17 | + AES/ECB/ISO10126Padding 32 16 | ||
| 18 | + AES/OFB/NoPadding 16 原始数据长度 | ||
| 19 | + AES/OFB/PKCS5Padding 32 16 | ||
| 20 | + AES/OFB/ISO10126Padding 32 16 | ||
| 21 | + AES/PCBC/NoPadding 16 不支持 | ||
| 22 | + AES/PCBC/PKCS5Padding 32 16 | ||
| 23 | + AES/PCBC/ISO10126Padding 32 16 | ||
| 24 | + */ | ||
| 25 | + //默认为 AES_CBC_PKCS5PADDING | ||
| 26 | + public final static String AES_DEFAULT = "AES"; | ||
| 27 | + public final static String AES_CBC_NOPADDING = "AES/CBC/NoPadding"; | ||
| 28 | + public final static String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding"; | ||
| 29 | + public final static String AES_CBC_ISO10126PADDING = "AES/CBC/ISO10126Padding"; | ||
| 30 | + public final static String AES_CFB_NOPADDING = "AES/CFB/NoPadding"; | ||
| 31 | + public final static String AES_CFB_PKCS5PADDING = "AES/CFB/PKCS5Padding"; | ||
| 32 | + public final static String AES_CFB_ISO10126PADDING = "AES/CFB/ISO10126Padding"; | ||
| 33 | + public final static String AES_ECB_NOPADDING = "AES/ECB/NoPadding"; | ||
| 34 | + public final static String AES_ECB_PKCS5PADDING = "AES/ECB/PKCS5Padding"; | ||
| 35 | + public final static String AES_ECB_ISO10126PADDING = "AES/ECB/ISO10126Padding"; | ||
| 36 | + public final static String AES_OFB_NOPADDING = "AES/OFB/NoPadding"; | ||
| 37 | + public final static String AES_OFB_PKCS5PADDING = "AES/OFB/PKCS5Padding"; | ||
| 38 | + public final static String AES_OFB_ISO10126PADDING = "AES/OFB/ISO10126Padding"; | ||
| 39 | + public final static String AES_PCBC_NOPADDING = "AES/PCBC/NoPadding"; | ||
| 40 | + public final static String AES_PCBC_PKCS5PADDING = "AES/PCBC/PKCS5Padding"; | ||
| 41 | + public final static String AES_PCBC_ISO10126PADDING = "AES/PCBC/ISO10126Padding"; | ||
| 42 | +} |
| ... | @@ -55,6 +55,8 @@ public class ConsumerWorker<K, V> implements Runnable { | ... | @@ -55,6 +55,8 @@ public class ConsumerWorker<K, V> implements Runnable { |
| 55 | if(isExpDmData(kafkaTemporaryStorage)){ | 55 | if(isExpDmData(kafkaTemporaryStorage)){ |
| 56 | //设置消息状态为待处理 | 56 | //设置消息状态为待处理 |
| 57 | kafkaTemporaryStorage.setStatus(KafkaStatusEnum.PENDING.getCode()); | 57 | kafkaTemporaryStorage.setStatus(KafkaStatusEnum.PENDING.getCode()); |
| 58 | + //将消息状态设置为已处理 | ||
| 59 | + kafkaTemporaryStorage.setStatusName(KafkaStatusEnum.PENDING.getName()); | ||
| 58 | //设置入库时间 | 60 | //设置入库时间 |
| 59 | kafkaTemporaryStorage.setCreateTime(new Date()); | 61 | kafkaTemporaryStorage.setCreateTime(new Date()); |
| 60 | //设置处理次数初始为0次 | 62 | //设置处理次数初始为0次 | ... | ... |
| ... | @@ -2,6 +2,7 @@ package com.fedex.connect.kafka.service.impl; | ... | @@ -2,6 +2,7 @@ package com.fedex.connect.kafka.service.impl; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.databind.ObjectMapper; | 3 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 4 | import com.fasterxml.jackson.databind.node.ObjectNode; | 4 | import com.fasterxml.jackson.databind.node.ObjectNode; |
| 5 | +import com.fedex.connect.common.dependencies.enums.sys.KafkaStatusEnum; | ||
| 5 | import com.fedex.connect.common.model.sys.KafkaStorageHistory; | 6 | import com.fedex.connect.common.model.sys.KafkaStorageHistory; |
| 6 | import com.fedex.connect.common.model.sys.KafkaTemporaryStorage; | 7 | import com.fedex.connect.common.model.sys.KafkaTemporaryStorage; |
| 7 | import com.fedex.connect.kafka.data.dto.DmProcessResults; | 8 | import com.fedex.connect.kafka.data.dto.DmProcessResults; |
| ... | @@ -118,6 +119,8 @@ public class KafkaDmServiceImpl extends BaseService implements ApplicationContex | ... | @@ -118,6 +119,8 @@ public class KafkaDmServiceImpl extends BaseService implements ApplicationContex |
| 118 | kafkaStorageHistory.setCreateTime(new Date()); | 119 | kafkaStorageHistory.setCreateTime(new Date()); |
| 119 | //将消息状态设置为已处理 | 120 | //将消息状态设置为已处理 |
| 120 | kafkaStorageHistory.setStatus(1L); | 121 | kafkaStorageHistory.setStatus(1L); |
| 122 | + //将消息状态设置为已处理 | ||
| 123 | + kafkaStorageHistory.setStatusName(KafkaStatusEnum.PROCESSED.getName()); | ||
| 121 | //设置运单号 | 124 | //设置运单号 |
| 122 | kafkaStorageHistory.setConsignmentCode(processResults.getConsignmentCode()); | 125 | kafkaStorageHistory.setConsignmentCode(processResults.getConsignmentCode()); |
| 123 | //保存至kafka历史表 | 126 | //保存至kafka历史表 | ... | ... |
| ... | @@ -115,6 +115,9 @@ public class Dm501Util { | ... | @@ -115,6 +115,9 @@ public class Dm501Util { |
| 115 | ceInfo.setShipperReference(dm501Consignment.getShipperReferenceNotes()); | 115 | ceInfo.setShipperReference(dm501Consignment.getShipperReferenceNotes()); |
| 116 | //件数 | 116 | //件数 |
| 117 | String quantity = dm501Consignment.getQuantity(); | 117 | String quantity = dm501Consignment.getQuantity(); |
| 118 | + //文件或包裹 | ||
| 119 | + ceInfo.setDocNondocFlag(dm501Consignment.getDocNondocFlag()); | ||
| 120 | + | ||
| 118 | if(Objects.nonNull(quantity)){ | 121 | if(Objects.nonNull(quantity)){ |
| 119 | ceInfo.setPieces(Long.valueOf(quantity)); | 122 | ceInfo.setPieces(Long.valueOf(quantity)); |
| 120 | } | 123 | } |
| ... | @@ -197,9 +200,9 @@ public class Dm501Util { | ... | @@ -197,9 +200,9 @@ public class Dm501Util { |
| 197 | Consignment resultConsignment = new Consignment(); | 200 | Consignment resultConsignment = new Consignment(); |
| 198 | BeanUtils.copyProperties(ceInfo,resultConsignment); | 201 | BeanUtils.copyProperties(ceInfo,resultConsignment); |
| 199 | //运单状态赋值为"待上传" | 202 | //运单状态赋值为"待上传" |
| 200 | - DictionaryEntries consignmentDicEntries = cacheSystem.getDicConsignmentStatus(ConsignmentStatusEnum.CONSIGNMENT_STATUS_01.getCode()); | 203 | +// DictionaryEntries consignmentDicEntries = cacheSystem.getDicConsignmentStatus(ConsignmentStatusEnum.CONSIGNMENT_STATUS_01.getCode()); |
| 201 | - resultConsignment.setStatusCode(consignmentDicEntries.getCode()); | 204 | +// resultConsignment.setStatusCode(consignmentDicEntries.getCode()); |
| 202 | - resultConsignment.setStatusName(consignmentDicEntries.getDescription()); | 205 | +// resultConsignment.setStatusName(consignmentDicEntries.getEnglishName()); |
| 203 | /** | 206 | /** |
| 204 | * 初始化运单表原产国、目的国 | 207 | * 初始化运单表原产国、目的国 |
| 205 | */ | 208 | */ | ... | ... |
| 1 | package com.fedex.connect.task.utils.sys; | 1 | package com.fedex.connect.task.utils.sys; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | +import com.fedex.connect.common.dependencies.enums.sys.KafkaStatusEnum; | ||
| 4 | import com.fedex.connect.common.dependencies.util.JsonToJava; | 5 | import com.fedex.connect.common.dependencies.util.JsonToJava; |
| 5 | import com.fedex.connect.common.dependencies.util.RPCUtils; | 6 | import com.fedex.connect.common.dependencies.util.RPCUtils; |
| 6 | import com.fedex.connect.common.model.sys.KafkaStorageHistory; | 7 | import com.fedex.connect.common.model.sys.KafkaStorageHistory; |
| ... | @@ -40,7 +41,9 @@ public class KafkaDmUtil { | ... | @@ -40,7 +41,9 @@ public class KafkaDmUtil { |
| 40 | //判断是否已经处理3次 | 41 | //判断是否已经处理3次 |
| 41 | if(kts.getFrequency().intValue() >= 3){ | 42 | if(kts.getFrequency().intValue() >= 3){ |
| 42 | //标注状态为2失败 | 43 | //标注状态为2失败 |
| 43 | - kts.setStatus(2L); | 44 | + kts.setStatus(KafkaStatusEnum.PROCESSING_FAILED.getCode()); |
| 45 | + //标注状态为2失败 | ||
| 46 | + kts.setStatusName(KafkaStatusEnum.PROCESSING_FAILED.getName()); | ||
| 44 | //备注重新处理原因 | 47 | //备注重新处理原因 |
| 45 | kts.setRemark((kts.getRemark() == null ? "" : kts.getRemark()) + "--->处理次数达到3次进行备份。"); | 48 | kts.setRemark((kts.getRemark() == null ? "" : kts.getRemark()) + "--->处理次数达到3次进行备份。"); |
| 46 | backHisList.add(kts); | 49 | backHisList.add(kts); | ... | ... |
-
Please register or login to post a comment