-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
src/main/java/com/example/demo_test/reflect/design/AbstractAPI.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.example.demo_test.reflect.design; | ||
|
||
public abstract class AbstractAPI { | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/example/demo_test/reflect/design/BankAPI.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.example.demo_test.reflect.design; | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.TYPE) | ||
@Documented | ||
@Inherited | ||
public @interface BankAPI { | ||
String desc() default ""; | ||
|
||
String url() default ""; | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/com/example/demo_test/reflect/design/BankAPIField.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.example.demo_test.reflect.design; | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
@Documented | ||
@Inherited | ||
public @interface BankAPIField { | ||
int order() default -1; | ||
|
||
int length() default -1; | ||
|
||
String type() default ""; | ||
} |
84 changes: 84 additions & 0 deletions
84
src/main/java/com/example/demo_test/reflect/design/BetterBankService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.example.demo_test.reflect.design; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.http.client.fluent.Request; | ||
import org.apache.commons.codec.digest.DigestUtils; | ||
import org.apache.http.entity.ContentType; | ||
|
||
import java.io.IOException; | ||
import java.math.BigDecimal; | ||
import java.math.RoundingMode; | ||
import java.util.Arrays; | ||
import java.util.Comparator; | ||
|
||
|
||
@Slf4j | ||
public class BetterBankService { | ||
|
||
public static String createUser(String name, String identity, String mobile, int age) throws IOException { | ||
CreateUserAPI createUserAPI = new CreateUserAPI(); | ||
createUserAPI.setName(name); | ||
createUserAPI.setIdentity(identity); | ||
createUserAPI.setAge(age); | ||
createUserAPI.setMobile(mobile); | ||
return remoteCall(createUserAPI); | ||
} | ||
|
||
public static String pay(long userId, BigDecimal amount) throws IOException { | ||
PayAPI payAPI = new PayAPI(); | ||
payAPI.setUserId(userId); | ||
payAPI.setAmount(amount); | ||
return remoteCall(payAPI); | ||
} | ||
|
||
private static String remoteCall(AbstractAPI api) throws IOException { | ||
//从BankAPI注解获取请求地址 | ||
BankAPI bankAPI = api.getClass().getAnnotation(BankAPI.class); | ||
bankAPI.url(); | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
Arrays.stream(api.getClass().getDeclaredFields()) //获得所有字段 | ||
.filter(field -> field.isAnnotationPresent(BankAPIField.class)) //查找标记了注解的字段 | ||
.sorted(Comparator.comparingInt(a -> a.getAnnotation(BankAPIField.class).order())) //根据注解中的order对字段排序 | ||
.peek(field -> field.setAccessible(true)) //设置可以访问私有字段 | ||
.forEach(field -> { | ||
//获得注解 | ||
BankAPIField bankAPIField = field.getAnnotation(BankAPIField.class); | ||
Object value = ""; | ||
try { | ||
//反射获取字段值 | ||
value = field.get(api); | ||
} catch (IllegalAccessException e) { | ||
e.printStackTrace(); | ||
} | ||
//根据字段类型以正确的填充方式格式化字符串 | ||
switch (bankAPIField.type()) { | ||
case "S": { | ||
stringBuilder.append(String.format("%-" + bankAPIField.length() + "s", value.toString()).replace(' ', '_')); | ||
break; | ||
} | ||
case "N": { | ||
stringBuilder.append(String.format("%" + bankAPIField.length() + "s", value.toString()).replace(' ', '0')); | ||
break; | ||
} | ||
case "M": { | ||
if (!(value instanceof BigDecimal)) | ||
throw new RuntimeException(String.format("{} 的 {} 必须是BigDecimal", api, field)); | ||
stringBuilder.append(String.format("%0" + bankAPIField.length() + "d", ((BigDecimal) value).setScale(2, RoundingMode.DOWN).multiply(new BigDecimal("100")).longValue())); | ||
break; | ||
} | ||
default: | ||
break; | ||
} | ||
}); | ||
//签名逻辑 | ||
stringBuilder.append(DigestUtils.md2Hex(stringBuilder.toString())); | ||
String param = stringBuilder.toString(); | ||
long begin = System.currentTimeMillis(); | ||
//发请求 | ||
String result = Request.Post("http://localhost:45678/reflection" + bankAPI.url()) | ||
.bodyString(param, ContentType.APPLICATION_JSON) | ||
.execute().returnContent().asString(); | ||
log.info("调用银行API {} url:{} 参数:{} 耗时:{}ms", bankAPI.desc(), bankAPI.url(), param, System.currentTimeMillis() - begin); | ||
return result; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/example/demo_test/reflect/design/CreateUserAPI.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.example.demo_test.reflect.design; | ||
|
||
import lombok.Data; | ||
|
||
@BankAPI(url = "/bank/createUser", desc = "创建用户接口") | ||
@Data | ||
public class CreateUserAPI extends AbstractAPI { | ||
@BankAPIField(order = 1, type = "S", length = 10) | ||
private String name; | ||
@BankAPIField(order = 2, type = "S", length = 18) | ||
private String identity; | ||
@BankAPIField(order = 4, type = "S", length = 11) | ||
private String mobile; | ||
@BankAPIField(order = 3, type = "N", length = 5) | ||
private int age; | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/example/demo_test/reflect/design/PayAPI.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.example.demo_test.reflect.design; | ||
|
||
import lombok.Data; | ||
|
||
import java.math.BigDecimal; | ||
|
||
@BankAPI(url = "/bank/pay", desc = "支付接口") | ||
@Data | ||
public class PayAPI extends AbstractAPI { | ||
@BankAPIField(order = 1, type = "N", length = 20) | ||
private long userId; | ||
@BankAPIField(order = 2, type = "M", length = 10) | ||
private BigDecimal amount; | ||
} |