Skip to content

Commit

Permalink
Merge pull request #5 from dustlight-cn/field
Browse files Browse the repository at this point in the history
Field
  • Loading branch information
Hansin1997 authored Apr 18, 2021
2 parents 3dace3a + 1a13d50 commit 23a6678
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 31 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<dependency>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>captcha-core</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion captcha-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>captcha</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>captcha-core</artifactId>
Expand Down
94 changes: 91 additions & 3 deletions captcha-core/src/main/java/cn/dustlight/captcha/Util.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package cn.dustlight.captcha;

import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.DefaultParameterNameDiscoverer;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class Util {

Expand All @@ -25,4 +27,90 @@ public static Map<String, Object> getParameters(Method method, Object[] argument
parameters.put(names[i], arguments[i]);
return parameters;
}

/* ===================================================================================================== */

public static class AnnotationFieldFinder<T extends Annotation> {

private ConcurrentHashMap<Class<?>, Vector<AnnotationField<T>>> cache;
private Class<T> annotationClazz;

private final static ConcurrentHashMap<Class<?>, AnnotationFieldFinder> finders = new ConcurrentHashMap<>();

public static <T extends Annotation> AnnotationFieldFinder<T> get(Class<T> annotationClazz) {
if (finders.containsKey(annotationClazz))
return finders.get(annotationClazz);
else {
AnnotationFieldFinder<T> finder = new AnnotationFieldFinder<>(annotationClazz);
finders.put(annotationClazz, finder);
return finder;
}
}

private AnnotationFieldFinder(Class<T> targetClazz) {
this.cache = new ConcurrentHashMap<>();
this.annotationClazz = targetClazz;
}

public Vector<AnnotationField<T>> find(Class<?> clazz) {
if (clazz == null)
return null;
if (cache.containsKey(clazz))
return cache.get(clazz);
else {
Vector<AnnotationField<T>> val = doProcess(clazz);
cache.put(clazz, val);
return val;
}
}

protected Vector<AnnotationField<T>> doProcess(Class<?> clazz) {
Vector<AnnotationField<T>> results = new Vector<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
T a;
if ((a = field.getAnnotation(annotationClazz)) != null) {
AnnotationField<T> annotationField = new AnnotationField<>();
annotationField.setAnnotation(a);
annotationField.setField(field);
results.add(annotationField);
}
}
return results;
}
}

public static class AnnotationField<T extends Annotation> {

private T annotation;
private Field field;

public T getAnnotation() {
return annotation;
}

public void setAnnotation(T annotation) {
this.annotation = annotation;
}

public Field getField() {
return field;
}

public void setField(Field field) {
this.field = field;
}

public Object read(Object instance) {
if (instance == null)
return null;
return new BeanWrapperImpl(instance).getPropertyValue(field.getName());
}

public void write(Object instance, Object value) {
if (instance == null)
return;
new BeanWrapperImpl(instance).setPropertyValue(field.getName(), value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

import java.lang.annotation.*;

@Target({ElementType.PARAMETER})
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
/**
* 验证码参数
* <p>
* 验证参数用于在生产端向消费端传递消息。
* 例如邮箱验证业务时,消费验证码成功后必须同时获取生产验证码时对应的邮箱。
* 那么只需在生产端对邮箱参数添加此注解,如: sendEmailCode(@RequestParam @CodeParam("email") String email)
* 在消费端时添加对应的参数即可获取注册邮箱:verifyEmail(@RequestParam @CodeValue String code, @CodeParam("email") String email)
* </p>
*/
public @interface CodeParam {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.lang.annotation.*;

@Target({ElementType.PARAMETER})
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;
import java.util.Vector;

public class SendCodeInterceptor implements MethodBeforeAdvice, Ordered {

Expand Down Expand Up @@ -66,6 +68,29 @@ public void before(Method method, Object[] objects, Object o) throws Throwable {
String key = codeParamAnnotation.value().length() > 0 ? codeParamAnnotation.value() : params[i].getName();
Object value = objects[i] != null ? objects[i] : codeParamAnnotation.defaultValue();
code.getData().put(key, value); // 存储验证码参数
} else if (objects[i] != null) {
Class<?> paramType = params[i].getType();
Vector<Util.AnnotationField<CodeValue>> codeValues = Util.AnnotationFieldFinder.get(CodeValue.class).find(paramType);
Vector<Util.AnnotationField<CodeParam>> codeParams = Util.AnnotationFieldFinder.get(CodeParam.class).find(paramType);
if (codeValues != null)
for (Util.AnnotationField<CodeValue> field : codeValues) {
if (!field.getAnnotation().value().equals(sendCodeAnnotation.value()))
continue;
Field f = field.getField();
field.write(objects[i], codeValue);
parameters.put(f.getName(), codeValue);
}
if (codeParams != null)
for (Util.AnnotationField<CodeParam> field : codeParams) {
if (!field.getAnnotation().value().equals(sendCodeAnnotation.value()))
continue;
Field f = field.getField();
String key = field.getAnnotation().value().length() > 0 ? field.getAnnotation().value() : f.getName();
Object value = field.read(objects[i]);
if (value == null)
value = field.getAnnotation().defaultValue();
code.getData().put(key, value); // 存储验证码参数
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;
import java.util.Vector;

public class VerifyCodeInterceptor implements MethodBeforeAdvice, Ordered {

public static final String CHANCE_KEY = "CHANCE";
private BeanFactory factory;
private int order;
private DefaultBeanProperties defaultBeanProperties;
Expand All @@ -29,22 +32,22 @@ public VerifyCodeInterceptor(DefaultBeanProperties defaultBeanProperties) {
}

boolean checkChance(Code code, int chance) {
if (code.getData().get("CHANCE") == null)
if (code.getData().get(CHANCE_KEY) == null)
return true;
Integer CHANCE = Integer.valueOf(code.getData().get("CHANCE").toString());
Integer CHANCE = Integer.valueOf(code.getData().get(VerifyCodeInterceptor.CHANCE_KEY).toString());
if (CHANCE >= chance)
return false;
return true;
}

@SuppressWarnings("unchecked")
void addChanceCount(Code code) {
if (code.getData().get("CHANCE") == null) {
code.getData().put("CHANCE", 1);
if (code.getData().get(CHANCE_KEY) == null) {
code.getData().put(CHANCE_KEY, 1);
return;
}
Integer CHANCE = Integer.valueOf(code.getData().get("CHANCE").toString());
code.getData().put("CHANCE", CHANCE + 1);
Integer CHANCE = Integer.valueOf(code.getData().get(VerifyCodeInterceptor.CHANCE_KEY).toString());
code.getData().put(VerifyCodeInterceptor.CHANCE_KEY, CHANCE + 1);
}

@SuppressWarnings("unchecked")
Expand All @@ -67,10 +70,9 @@ public void before(Method method, Object[] objects, Object o) throws Throwable {

Code code = store.load(verifyCodeAnnotation.value(), parameters);
Object codeValue = code.getValue();
Object targetValue = parameters.get(verifyCodeAnnotation.value());
Object targetValue = parameters.get(verifyCodeAnnotation.value()); // 先取同名参数值为默认值,之后再扫描 @CodeValue 替代
Parameter[] params = method.getParameters();


if (params != null && objects != null) {
for (int i = 0, len = Math.min(params.length, objects.length); i < len; i++) {
CodeParam codeParamAnnotation;
Expand All @@ -87,6 +89,30 @@ public void before(Method method, Object[] objects, Object o) throws Throwable {
if (value == null && params[i].getType().isAssignableFrom(String.class))
value = codeParamAnnotation.defaultValue();
objects[i] = code.getData().getOrDefault(key, value); // 将验证码参数注入方法参数
} else if (objects[i] != null) {
Class<?> paramType = params[i].getType();
Vector<Util.AnnotationField<CodeValue>> codeValues = Util.AnnotationFieldFinder.get(CodeValue.class).find(paramType);
Vector<Util.AnnotationField<CodeParam>> codeParams = Util.AnnotationFieldFinder.get(CodeParam.class).find(paramType);
if (codeValues != null)
for (Util.AnnotationField<CodeValue> field : codeValues) {
if (!field.getAnnotation().value().equals(verifyCodeAnnotation.value()))
continue;
Field f = field.getField();
targetValue = field.read(objects[i]);
field.write(objects[i], codeValue);
parameters.put(f.getName(), codeValue);
}
if (codeParams != null)
for (Util.AnnotationField<CodeParam> field : codeParams) {
if (!field.getAnnotation().value().equals(verifyCodeAnnotation.value()))
continue;
Field f = field.getField();
String key = field.getAnnotation().value().length() > 0 ? field.getAnnotation().value() : f.getName();
Object value = code.getData() == null ? null : code.getData().get(key);
if (value == null && f.getType().isAssignableFrom(String.class))
value = field.getAnnotation().defaultValue();
field.write(objects[i], code.getData().getOrDefault(key, value));
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/email-sender/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<dependency>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>email-sender</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion extensions/email-sender/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>captcha</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>email-sender</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extensions/reCAPTCHA/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<dependency>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>recaptcha</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion extensions/reCAPTCHA/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>captcha</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>recaptcha</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extensions/redis-store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<dependency>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>redis-store</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion extensions/redis-store/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>captcha</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>redis-store</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extensions/tencent-sms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<dependency>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>tencent-sms</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion extensions/tencent-sms/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>cn.dustlight.captcha</groupId>
<artifactId>captcha</artifactId>
<version>0.0.6</version>
<version>0.0.7</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>tencent-sms</artifactId>
Expand Down
Loading

0 comments on commit 23a6678

Please sign in to comment.