diff --git a/.gitignore b/.gitignore index 7050f4c..e9c4437 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ buildNumber.properties !/.mvn/wrapper/maven-wrapper.jar .idea/* *.iml +src/main/java/cn/licoy/encryptbody/test diff --git a/src/main/java/cn/licoy/encryptbody/advice/DecryptRequestBodyAdvice.java b/src/main/java/cn/licoy/encryptbody/advice/DecryptRequestBodyAdvice.java index 38cc43d..6c0e2fd 100644 --- a/src/main/java/cn/licoy/encryptbody/advice/DecryptRequestBodyAdvice.java +++ b/src/main/java/cn/licoy/encryptbody/advice/DecryptRequestBodyAdvice.java @@ -1,14 +1,15 @@ package cn.licoy.encryptbody.advice; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.RSA; +import cn.licoy.encryptbody.annotation.FieldBody; import cn.licoy.encryptbody.annotation.decrypt.AESDecryptBody; import cn.licoy.encryptbody.annotation.decrypt.DESDecryptBody; import cn.licoy.encryptbody.annotation.decrypt.DecryptBody; import cn.licoy.encryptbody.annotation.decrypt.RSADecryptBody; -import cn.licoy.encryptbody.annotation.encrypt.RSAEncryptBody; import cn.licoy.encryptbody.bean.DecryptAnnotationInfoBean; import cn.licoy.encryptbody.bean.DecryptHttpInputMessage; import cn.licoy.encryptbody.config.EncryptBodyConfig; @@ -16,6 +17,7 @@ import cn.licoy.encryptbody.exception.DecryptBodyFailException; import cn.licoy.encryptbody.exception.DecryptMethodNotFoundException; import cn.licoy.encryptbody.util.CommonUtils; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.Order; @@ -24,7 +26,8 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; -import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -44,25 +47,35 @@ public class DecryptRequestBodyAdvice implements RequestBodyAdvice { private final EncryptBodyConfig config; - public DecryptRequestBodyAdvice(EncryptBodyConfig config) { + private final ObjectMapper objectMapper; + + public DecryptRequestBodyAdvice(ObjectMapper objectMapper, EncryptBodyConfig config) { + this.objectMapper = objectMapper; this.config = config; } @Override public boolean supports(MethodParameter methodParameter, Type targetType, Class extends HttpMessageConverter>> converterType) { - Annotation[] annotations = methodParameter.getDeclaringClass().getAnnotations(); - if (annotations.length > 0) { - for (Annotation annotation : annotations) { - if (annotation instanceof DecryptBody || annotation instanceof AESDecryptBody || annotation instanceof DESDecryptBody || annotation instanceof RSADecryptBody) { + if (this.hasDecryptAnnotation(methodParameter.getDeclaringClass())) { + return true; + } + Method method = methodParameter.getMethod(); + if (method != null) { + if (this.hasDecryptAnnotation(method)) { + return true; + } + Class>[] parameterTypes = method.getParameterTypes(); + for (Class> parameterType : parameterTypes) { + if (this.hasDecryptAnnotation(parameterType)) { return true; } } } - Method method = methodParameter.getMethod(); - if (method == null) { - return false; - } - return method.isAnnotationPresent(DecryptBody.class) || method.isAnnotationPresent(AESDecryptBody.class) || method.isAnnotationPresent(DESDecryptBody.class) || method.isAnnotationPresent(RSADecryptBody.class); + return false; + } + + private boolean hasDecryptAnnotation(AnnotatedElement annotatedElement) { + return annotatedElement.isAnnotationPresent(DecryptBody.class) || annotatedElement.isAnnotationPresent(AESDecryptBody.class) || annotatedElement.isAnnotationPresent(DESDecryptBody.class) || annotatedElement.isAnnotationPresent(RSADecryptBody.class); } @Override @@ -81,12 +94,33 @@ public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodPara if (body == null || StrUtil.isEmpty(body)) { throw new DecryptBodyFailException("The request body is NULL or an empty string, so the decryption failed." + " (请求正文为NULL或为空字符串,因此解密失败。)"); } + Class> targetTypeClass; + try { + targetTypeClass = Class.forName(targetType.getTypeName()); + } catch (ClassNotFoundException e) { + throw new DecryptBodyFailException(e.getMessage()); + } String decryptBody = null; - DecryptAnnotationInfoBean methodAnnotation = this.getMethodAnnotation(parameter); + DecryptAnnotationInfoBean methodAnnotation = this.getDecryptAnnotation(parameter.getMethod()); if (methodAnnotation != null) { decryptBody = switchDecrypt(body, methodAnnotation); + } else if (this.hasDecryptAnnotation(targetTypeClass)) { + if (targetTypeClass.isAnnotationPresent(FieldBody.class)) { + try { + Object bodyInstance = objectMapper.readValue(body, targetTypeClass); + Object decryptBodyInstance = this.eachClassField(bodyInstance, targetTypeClass); + decryptBody = objectMapper.writeValueAsString(decryptBodyInstance); + } catch (Exception e) { + throw new DecryptBodyFailException(e.getMessage()); + } + } else { + DecryptAnnotationInfoBean classAnnotation = this.getDecryptAnnotation(targetTypeClass); + if (classAnnotation != null) { + decryptBody = switchDecrypt(body, classAnnotation); + } + } } else { - DecryptAnnotationInfoBean classAnnotation = this.getClassAnnotation(parameter.getDeclaringClass()); + DecryptAnnotationInfoBean classAnnotation = this.getDecryptAnnotation(parameter.getDeclaringClass()); if (classAnnotation != null) { decryptBody = switchDecrypt(body, classAnnotation); } @@ -106,37 +140,65 @@ public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodPa return body; } + private Object eachClassField(Object body, Class> clazz) { + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field field : declaredFields) { + field.setAccessible(true); + DecryptAnnotationInfoBean decryptAnnotation = this.getDecryptAnnotation(field); + Class> type = field.getType(); + if (decryptAnnotation != null) { + FieldBody fieldBody = field.getAnnotation(FieldBody.class); + if (fieldBody != null) { + Field setField = ReflectUtil.getField(clazz, fieldBody.field()); + if (setField != null && setField.getType().equals(String.class)) { + Object fieldValue = ReflectUtil.getFieldValue(body, setField); + String decryptResult = this.switchDecrypt(String.valueOf(fieldValue), decryptAnnotation); + ReflectUtil.setFieldValue(body, field, decryptResult); + } + } else if (type.equals(String.class)) { + String decryptResult = this.switchDecrypt(String.valueOf(ReflectUtil.getFieldValue(body, field)), decryptAnnotation); + ReflectUtil.setFieldValue(body, field, decryptResult); + } + } else if (!CommonUtils.isConvertToString(type)) { + Object fieldValue = ReflectUtil.getFieldValue(body, field); + if (fieldValue != null) { + this.eachClassField(fieldValue, type); + } + } + } + return body; + } + /** - * 获取方法控制器上的加密注解信息 + * 获取解密注解的数据 * - * @param methodParameter 控制器方法 - * @return 加密注解信息 + * @param annotatedElement 注解元素 + * @return 解密注解组装数据 */ - private DecryptAnnotationInfoBean getMethodAnnotation(MethodParameter methodParameter) { - Method method = methodParameter.getMethod(); - if (method == null) { + private DecryptAnnotationInfoBean getDecryptAnnotation(AnnotatedElement annotatedElement) { + if (annotatedElement == null) { return null; } - if (method.isAnnotationPresent(DecryptBody.class)) { - DecryptBody decryptBody = methodParameter.getMethodAnnotation(DecryptBody.class); + if (annotatedElement.isAnnotationPresent(DecryptBody.class)) { + DecryptBody decryptBody = annotatedElement.getAnnotation(DecryptBody.class); if (decryptBody != null) { return DecryptAnnotationInfoBean.builder().decryptBodyMethod(decryptBody.value()).key(decryptBody.otherKey()).build(); } } - if (method.isAnnotationPresent(DESDecryptBody.class)) { - DESDecryptBody decryptBody = methodParameter.getMethodAnnotation(DESDecryptBody.class); + if (annotatedElement.isAnnotationPresent(DESDecryptBody.class)) { + DESDecryptBody decryptBody = annotatedElement.getAnnotation(DESDecryptBody.class); if (decryptBody != null) { return DecryptAnnotationInfoBean.builder().decryptBodyMethod(DecryptBodyMethod.DES).key(decryptBody.key()).build(); } } - if (method.isAnnotationPresent(AESDecryptBody.class)) { - AESDecryptBody decryptBody = methodParameter.getMethodAnnotation(AESDecryptBody.class); + if (annotatedElement.isAnnotationPresent(AESDecryptBody.class)) { + AESDecryptBody decryptBody = annotatedElement.getAnnotation(AESDecryptBody.class); if (decryptBody != null) { return DecryptAnnotationInfoBean.builder().decryptBodyMethod(DecryptBodyMethod.AES).key(decryptBody.key()).build(); } } - if (method.isAnnotationPresent(RSADecryptBody.class)) { - RSADecryptBody decryptBody = methodParameter.getMethodAnnotation(RSADecryptBody.class); + if (annotatedElement.isAnnotationPresent(RSADecryptBody.class)) { + RSADecryptBody decryptBody = annotatedElement.getAnnotation(RSADecryptBody.class); if (decryptBody != null) { return DecryptAnnotationInfoBean.builder().decryptBodyMethod(DecryptBodyMethod.RSA).key(decryptBody.key()).rsaKeyType(decryptBody.type()).build(); } @@ -144,31 +206,6 @@ private DecryptAnnotationInfoBean getMethodAnnotation(MethodParameter methodPara return null; } - /** - * 获取类控制器上的加密注解信息 - * - * @param clazz 控制器类 - * @return 加密注解信息 - */ - private DecryptAnnotationInfoBean getClassAnnotation(Class> clazz) { - Annotation[] annotations = clazz.getDeclaredAnnotations(); - if (annotations.length > 0) { - for (Annotation annotation : annotations) { - if (annotation instanceof DecryptBody) { - DecryptBody decryptBody = (DecryptBody) annotation; - return DecryptAnnotationInfoBean.builder().decryptBodyMethod(decryptBody.value()).key(decryptBody.otherKey()).build(); - } - if (annotation instanceof DESDecryptBody) { - return DecryptAnnotationInfoBean.builder().decryptBodyMethod(DecryptBodyMethod.DES).key(((DESDecryptBody) annotation).key()).build(); - } - if (annotation instanceof AESDecryptBody) { - return DecryptAnnotationInfoBean.builder().decryptBodyMethod(DecryptBodyMethod.AES).key(((AESDecryptBody) annotation).key()).build(); - } - } - } - return null; - } - /** * 选择加密方式并进行解密 diff --git a/src/main/java/cn/licoy/encryptbody/advice/EncryptResponseBodyAdvice.java b/src/main/java/cn/licoy/encryptbody/advice/EncryptResponseBodyAdvice.java index 6a91446..3a87d8e 100644 --- a/src/main/java/cn/licoy/encryptbody/advice/EncryptResponseBodyAdvice.java +++ b/src/main/java/cn/licoy/encryptbody/advice/EncryptResponseBodyAdvice.java @@ -1,7 +1,9 @@ package cn.licoy.encryptbody.advice; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.RSA; +import cn.licoy.encryptbody.annotation.FieldBody; import cn.licoy.encryptbody.annotation.encrypt.*; import cn.licoy.encryptbody.bean.EncryptAnnotationInfoBean; import cn.licoy.encryptbody.config.EncryptBodyConfig; @@ -24,7 +26,8 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; -import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -56,169 +59,141 @@ public EncryptResponseBodyAdvice(ObjectMapper objectMapper, EncryptBodyConfig co @Override public boolean supports(MethodParameter returnType, Class converterType) { - Annotation[] annotations = returnType.getDeclaringClass().getAnnotations(); - if (annotations.length > 0) { - for (Annotation annotation : annotations) { - if (annotation instanceof EncryptBody || - annotation instanceof AESEncryptBody || - annotation instanceof DESEncryptBody || - annotation instanceof RSAEncryptBody || - annotation instanceof MD5EncryptBody || - annotation instanceof SHAEncryptBody) { - return true; - } - } + Class> declaringClass = returnType.getDeclaringClass(); + if (this.hasEncryptAnnotation(declaringClass)) { + return true; } Method method = returnType.getMethod(); if (method != null) { - return method.isAnnotationPresent(EncryptBody.class) || - method.isAnnotationPresent(AESEncryptBody.class) || - method.isAnnotationPresent(DESEncryptBody.class) || - method.isAnnotationPresent(RSAEncryptBody.class) || - method.isAnnotationPresent(MD5EncryptBody.class) || - method.isAnnotationPresent(SHAEncryptBody.class); + Class> returnValueType = method.getReturnType(); + return this.hasEncryptAnnotation(method) || this.hasEncryptAnnotation(returnValueType); } return false; } + private boolean hasEncryptAnnotation(AnnotatedElement annotatedElement) { + if (annotatedElement == null) { + return false; + } + return annotatedElement.isAnnotationPresent(EncryptBody.class) || annotatedElement.isAnnotationPresent(AESEncryptBody.class) || annotatedElement.isAnnotationPresent(DESEncryptBody.class) || annotatedElement.isAnnotationPresent(RSAEncryptBody.class) || annotatedElement.isAnnotationPresent(MD5EncryptBody.class) || annotatedElement.isAnnotationPresent(SHAEncryptBody.class); + } + @Override - public String beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, - Class extends HttpMessageConverter>> selectedConverterType, - ServerHttpRequest request, ServerHttpResponse response) { + public String beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class extends HttpMessageConverter>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if (body == null) { return null; } - String str; - if (body instanceof String || body instanceof Number || body instanceof Boolean) { - str = String.valueOf(body); - } else { - try { - str = objectMapper.writeValueAsString(body); - } catch (JsonProcessingException e) { - e.printStackTrace(); - throw new EncryptBodyFailException(e.getMessage()); + String str = CommonUtils.convertToStringOrJson(body, objectMapper); + response.getHeaders().setContentType(MediaType.TEXT_PLAIN); + EncryptAnnotationInfoBean classAnnotation = this.getEncryptAnnotation(returnType.getDeclaringClass()); + Method method = returnType.getMethod(); + if (method != null) { + // 从方法上 + EncryptAnnotationInfoBean methodAnnotation = this.getEncryptAnnotation(method); + if (methodAnnotation != null) { + return switchEncrypt(str, methodAnnotation); + } + // 从方法返回值上 + Class> methodReturnType = method.getReturnType(); + if (methodReturnType.isAnnotationPresent(FieldBody.class)) { + Object encryptResult = this.eachClassField(body, method.getReturnType()); + try { + return objectMapper.writeValueAsString(encryptResult); + } catch (JsonProcessingException e) { + throw new EncryptBodyFailException(e.getMessage()); + } + } else { + classAnnotation = this.getEncryptAnnotation(method.getReturnType()); + if (classAnnotation != null) { + return switchEncrypt(str, classAnnotation); + } } } - response.getHeaders().setContentType(MediaType.TEXT_PLAIN); - EncryptAnnotationInfoBean classAnnotation = getClassAnnotation(returnType.getDeclaringClass()); + // 从声明类上 if (classAnnotation != null) { return switchEncrypt(str, classAnnotation); } - EncryptAnnotationInfoBean methodAnnotation = getMethodAnnotation(returnType); - if (methodAnnotation != null) { - return switchEncrypt(str, methodAnnotation); - } throw new EncryptBodyFailException(); } + private Object eachClassField(Object body, Class> returnTypeClass) { + Field[] fields = returnTypeClass.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + Class> type = field.getType(); + EncryptAnnotationInfoBean encryptAnnotation = this.getEncryptAnnotation(field); + if (encryptAnnotation != null) { + Object fieldValue = ReflectUtil.getFieldValue(body, field); + if (fieldValue != null) { + String str = CommonUtils.convertToStringOrJson(fieldValue, objectMapper); + String encryptResult = this.switchEncrypt(str, encryptAnnotation); + if (type.equals(String.class)) { + ReflectUtil.setFieldValue(body, field, encryptResult); + } else { + FieldBody fieldBody = field.getAnnotation(FieldBody.class); + if (fieldBody != null) { + Field setField = ReflectUtil.getField(returnTypeClass, fieldBody.field()); + if (setField != null && setField.getType().equals(String.class)) { + ReflectUtil.setFieldValue(body, fieldBody.field(), encryptResult); + if (fieldBody.clearValue()) { + ReflectUtil.setFieldValue(body, field, null); + } + } + } + } + } + } else if (!CommonUtils.isConvertToString(type)) { + Object fieldValue = ReflectUtil.getFieldValue(body, field); + if (fieldValue != null) { + this.eachClassField(fieldValue, type); + } + } + } + return body; + } + /** - * 获取方法控制器上的加密注解信息 + * 获取加密注解的数据 * - * @param methodParameter 控制器方法 - * @return 加密注解信息 + * @param annotatedElement 注解元素 + * @return 加密注解组装数据 */ - private EncryptAnnotationInfoBean getMethodAnnotation(MethodParameter methodParameter) { - Method method = methodParameter.getMethod(); - if (method == null) { + private EncryptAnnotationInfoBean getEncryptAnnotation(AnnotatedElement annotatedElement) { + if (annotatedElement == null) { return null; } - if (method.isAnnotationPresent(EncryptBody.class)) { - EncryptBody encryptBody = methodParameter.getMethodAnnotation(EncryptBody.class); + if (annotatedElement.isAnnotationPresent(EncryptBody.class)) { + EncryptBody encryptBody = annotatedElement.getAnnotation(EncryptBody.class); if (encryptBody != null) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(encryptBody.value()) - .key(encryptBody.otherKey()) - .shaEncryptType(encryptBody.shaType()) - .build(); + return EncryptAnnotationInfoBean.builder().encryptBodyMethod(encryptBody.value()).key(encryptBody.otherKey()).shaEncryptType(encryptBody.shaType()).build(); } } - if (method.isAnnotationPresent(MD5EncryptBody.class)) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.MD5) - .build(); + if (annotatedElement.isAnnotationPresent(MD5EncryptBody.class)) { + return EncryptAnnotationInfoBean.builder().encryptBodyMethod(EncryptBodyMethod.MD5).build(); } - if (method.isAnnotationPresent(SHAEncryptBody.class)) { - SHAEncryptBody encryptBody = methodParameter.getMethodAnnotation(SHAEncryptBody.class); + if (annotatedElement.isAnnotationPresent(SHAEncryptBody.class)) { + SHAEncryptBody encryptBody = annotatedElement.getAnnotation(SHAEncryptBody.class); if (encryptBody != null) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.SHA) - .shaEncryptType(encryptBody.value()) - .build(); + return EncryptAnnotationInfoBean.builder().encryptBodyMethod(EncryptBodyMethod.SHA).shaEncryptType(encryptBody.value()).build(); } } - if (method.isAnnotationPresent(DESEncryptBody.class)) { - DESEncryptBody encryptBody = methodParameter.getMethodAnnotation(DESEncryptBody.class); + if (annotatedElement.isAnnotationPresent(DESEncryptBody.class)) { + DESEncryptBody encryptBody = annotatedElement.getAnnotation(DESEncryptBody.class); if (encryptBody != null) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.DES) - .key(encryptBody.key()) - .build(); + return EncryptAnnotationInfoBean.builder().encryptBodyMethod(EncryptBodyMethod.DES).key(encryptBody.key()).build(); } } - if (method.isAnnotationPresent(AESEncryptBody.class)) { - AESEncryptBody encryptBody = methodParameter.getMethodAnnotation(AESEncryptBody.class); + if (annotatedElement.isAnnotationPresent(AESEncryptBody.class)) { + AESEncryptBody encryptBody = annotatedElement.getAnnotation(AESEncryptBody.class); if (encryptBody != null) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.AES) - .key(encryptBody.key()) - .build(); + return EncryptAnnotationInfoBean.builder().encryptBodyMethod(EncryptBodyMethod.AES).key(encryptBody.key()).build(); } } - if (method.isAnnotationPresent(RSAEncryptBody.class)) { - RSAEncryptBody encryptBody = methodParameter.getMethodAnnotation(RSAEncryptBody.class); + if (annotatedElement.isAnnotationPresent(RSAEncryptBody.class)) { + RSAEncryptBody encryptBody = annotatedElement.getAnnotation(RSAEncryptBody.class); if (encryptBody != null) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.RSA) - .key(encryptBody.key()) - .rsaKeyType(encryptBody.type()) - .build(); - } - } - return null; - } - - /** - * 获取类控制器上的加密注解信息 - * - * @param clazz 控制器类 - * @return 加密注解信息 - */ - private EncryptAnnotationInfoBean getClassAnnotation(Class> clazz) { - Annotation[] annotations = clazz.getDeclaredAnnotations(); - if (annotations.length > 0) { - for (Annotation annotation : annotations) { - if (annotation instanceof EncryptBody) { - EncryptBody encryptBody = (EncryptBody) annotation; - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(encryptBody.value()) - .key(encryptBody.otherKey()) - .shaEncryptType(encryptBody.shaType()) - .build(); - } - if (annotation instanceof MD5EncryptBody) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.MD5) - .build(); - } - if (annotation instanceof SHAEncryptBody) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.SHA) - .shaEncryptType(((SHAEncryptBody) annotation).value()) - .build(); - } - if (annotation instanceof DESEncryptBody) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.DES) - .key(((DESEncryptBody) annotation).key()) - .build(); - } - if (annotation instanceof AESEncryptBody) { - return EncryptAnnotationInfoBean.builder() - .encryptBodyMethod(EncryptBodyMethod.AES) - .key(((AESEncryptBody) annotation).key()) - .build(); - } + return EncryptAnnotationInfoBean.builder().encryptBodyMethod(EncryptBodyMethod.RSA).key(encryptBody.key()).rsaKeyType(encryptBody.type()).build(); } } return null; diff --git a/src/main/java/cn/licoy/encryptbody/annotation/FieldBody.java b/src/main/java/cn/licoy/encryptbody/annotation/FieldBody.java new file mode 100644 index 0000000..0286805 --- /dev/null +++ b/src/main/java/cn/licoy/encryptbody/annotation/FieldBody.java @@ -0,0 +1,32 @@ +package cn.licoy.encryptbody.annotation; + +import java.lang.annotation.*; + +/** + * 字段编码/加解密主体 + * + * @author Licoy + * @date 2022/5/15 + */ +@Target(value = {ElementType.TYPE, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface FieldBody { + + /** + *
设置字段
+ *如果需要编码/加密的字段不是String类型,则加密结果是无法写入的,所以需要定义写入到指定字段。
+ *此方法只在字段属性上生效
+ * + * @return 字段名称 + */ + String field() default ""; + + /** + * 若{setField}生效,则编码/加密成功之后清除原字段上的值 + * + * @return 是否清除 + */ + boolean clearValue() default true; + +} diff --git a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/AESDecryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/AESDecryptBody.java index 847ae74..94e9835 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/AESDecryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/AESDecryptBody.java @@ -7,7 +7,7 @@ * @version 2018/9/7 * @see DecryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AESDecryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DESDecryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DESDecryptBody.java index 9b4966c..bae9add 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DESDecryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DESDecryptBody.java @@ -7,7 +7,7 @@ * @version 2018/9/7 * @see DecryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DESDecryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DecryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DecryptBody.java index 889a2a9..98e95e0 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DecryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/DecryptBody.java @@ -10,7 +10,7 @@ * @author licoy.cn * @version 2018/9/7 */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DecryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/RSADecryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/RSADecryptBody.java index 75ad62e..2b8fd09 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/decrypt/RSADecryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/decrypt/RSADecryptBody.java @@ -9,7 +9,7 @@ * @version 2018/9/7 * @see DecryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RSADecryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/AESEncryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/AESEncryptBody.java index a3526f1..d56b815 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/AESEncryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/AESEncryptBody.java @@ -7,7 +7,7 @@ * @version 2018/9/4 * @see EncryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD, ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AESEncryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/DESEncryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/DESEncryptBody.java index 4ac1448..233ebc0 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/DESEncryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/DESEncryptBody.java @@ -7,7 +7,7 @@ * @version 2018/9/4 * @see EncryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DESEncryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/EncryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/EncryptBody.java index 623836f..f755ce6 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/EncryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/EncryptBody.java @@ -11,7 +11,7 @@ * @author licoy.cn * @version 2018/9/4 */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EncryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/MD5EncryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/MD5EncryptBody.java index 477061e..6905078 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/MD5EncryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/MD5EncryptBody.java @@ -7,7 +7,7 @@ * @version 2018/9/4 * @see EncryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MD5EncryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/RSAEncryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/RSAEncryptBody.java index 108a637..7b3a278 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/RSAEncryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/RSAEncryptBody.java @@ -9,7 +9,7 @@ * @version 2018/9/4 * @see EncryptBody */ -@Target(value = {ElementType.METHOD, ElementType.TYPE}) +@Target(value = {ElementType.METHOD, ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RSAEncryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/SHAEncryptBody.java b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/SHAEncryptBody.java index 7a883a3..f63a5cf 100644 --- a/src/main/java/cn/licoy/encryptbody/annotation/encrypt/SHAEncryptBody.java +++ b/src/main/java/cn/licoy/encryptbody/annotation/encrypt/SHAEncryptBody.java @@ -9,7 +9,7 @@ * @version 2018/9/4 * @see EncryptBody */ -@Target(value = {ElementType.METHOD,ElementType.TYPE}) +@Target(value = {ElementType.METHOD,ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SHAEncryptBody { diff --git a/src/main/java/cn/licoy/encryptbody/util/CommonUtils.java b/src/main/java/cn/licoy/encryptbody/util/CommonUtils.java index 483f4ef..fd5a293 100644 --- a/src/main/java/cn/licoy/encryptbody/util/CommonUtils.java +++ b/src/main/java/cn/licoy/encryptbody/util/CommonUtils.java @@ -1,11 +1,15 @@ package cn.licoy.encryptbody.util; +import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.RSA; import cn.licoy.encryptbody.bean.ISecurityInfo; +import cn.licoy.encryptbody.exception.EncryptBodyFailException; import cn.licoy.encryptbody.exception.IllegalSecurityTypeException; import cn.licoy.encryptbody.exception.KeyNotConfiguredException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; /** *工具类
@@ -25,6 +29,12 @@ public static String checkAndGetKey(String k1, String k2, String keyName) { return k1; } + /** + * 根据信息对象获取RSA实例 + * + * @param info 信息 + * @return rsa + */ public static RSA infoBeanToRsaInstance(ISecurityInfo info) { RSA rsa; switch (info.getRsaKeyType()) { @@ -40,4 +50,33 @@ public static RSA infoBeanToRsaInstance(ISecurityInfo info) { return rsa; } + /** + * 是否转换为string + * + * @param clazz class + * @return 是否 + */ + public static boolean isConvertToString(Class> clazz) { + return clazz.equals(String.class) || ClassUtil.isPrimitiveWrapper(clazz); + } + + /** + * 转换为string + * + * @param val 数据 + * @param mapper jackson + * @return string + */ + public static String convertToStringOrJson(Object val, ObjectMapper mapper) { + if (isConvertToString(val.getClass())) { + return String.valueOf(val); + } + try { + return mapper.writeValueAsString(val); + } catch (JsonProcessingException e) { + e.printStackTrace(); + throw new EncryptBodyFailException(e.getMessage()); + } + } + }