动态执行bean对象的方法
Dynamic execution of the methods of bean object
目前我有一个要求我们的后端 spring rest api 将接收加密 json 格式的数据(很少有字段是加密的,很少有字段是纯文本)
然后应用解密,然后对数据应用一些业务逻辑,最后将数据存储到数据库中。
此解密逻辑正在重复多个服务实现方法。
所以我们决定将解密逻辑与实际业务逻辑隔离。
我正在使用 spring aop 解密数据,解密后
我传递给服务层方法的对象。
但是我的服务层方法包含不同类型的对象作为参数
例如:
processEmployee(EmployeeRequest request)
procesStudent(StudentRequest request)
我正在寻找一种方法如何动态更改
同一对象字段上的数据本身(例如:EmployeeRequest、StudentRequest)
我尝试了以下方法并坚持执行第 4 步。
1.Introduced 一个新注释。
2.Annotate 那些具有加密数据的字段。
3.Retrieve 所有带注释的字段。
4.Each 字段数据我们将应用解密逻辑和
解密后的数据将再次注入同一字段
我在寻找 api 来实现第 4 步?
有没有api可以动态执行
同一对象上的方法
或任何参考请指出我。
我的建议是不要对加密/解密使用相同的 POJO class。它让以后的使用变得混乱(好像我收到了一个 EmployeeRequest 实例,它是否被解密?),并且还限制了类型(因为你的 encrypted/decrypted 数据必须是相同的类型)。
现在,对于实施,您有两个选择:
- 使用显式
ConversionService
注册转换器:
@Component
public class EmployeeRequestConverter implements Converter<EmployeeRequest, EmployeeRequest> {
@Override
public EmployeeRequest convert(EmployeeRequest source) {
// Apply your decryption logic
}
}
为其他请求对象制作类似的转换器。
现在在您的控制器中:
public class MyController {
private ConversionService conversionService;
private MyService myService;
@RequestMapping(...)
public void aRequest(@RequestBody EmployeeRequest request) {
myService.execute(conversionService.convert(request, EmployeeRequest.class));
}
}
- 使用反射。
前提条件:您在加密字段上有 @Encrypted
注释。
与第一个解决方案不同,您不需要为每种类型的请求创建显式转换器。
@Service
public class DecryptionService {
public void <T> T decrypt(T input) {
Field[] fields = input.getClass().getDeclaredFields();
for (Field field : fields) {
Encrypted encrypted = field.getAnnotation(Encrypted.class);
if (encrypted != null) {
try{
field.setAccessible(true);
Object val = field.get(input);
// Base on @Encrypted annotation in your val, do the decryption
Object decryptedVal = ...;
field.set(input, decryptedVal);
} catch (Exception ex) {
}
}
}
}
}
现在您可以为您的控制器申请此服务了。
您可能想要缓存 Class.getDeclaredFields()
和 Class<?> -> @Encrypted fields
之间的映射以提高性能。
目前我有一个要求我们的后端 spring rest api 将接收加密 json 格式的数据(很少有字段是加密的,很少有字段是纯文本) 然后应用解密,然后对数据应用一些业务逻辑,最后将数据存储到数据库中。
此解密逻辑正在重复多个服务实现方法。 所以我们决定将解密逻辑与实际业务逻辑隔离。
我正在使用 spring aop 解密数据,解密后 我传递给服务层方法的对象。
但是我的服务层方法包含不同类型的对象作为参数
例如:
processEmployee(EmployeeRequest request)
procesStudent(StudentRequest request)
我正在寻找一种方法如何动态更改 同一对象字段上的数据本身(例如:EmployeeRequest、StudentRequest)
我尝试了以下方法并坚持执行第 4 步。
1.Introduced 一个新注释。
2.Annotate 那些具有加密数据的字段。
3.Retrieve 所有带注释的字段。
4.Each 字段数据我们将应用解密逻辑和 解密后的数据将再次注入同一字段
我在寻找 api 来实现第 4 步?
有没有api可以动态执行 同一对象上的方法 或任何参考请指出我。
我的建议是不要对加密/解密使用相同的 POJO class。它让以后的使用变得混乱(好像我收到了一个 EmployeeRequest 实例,它是否被解密?),并且还限制了类型(因为你的 encrypted/decrypted 数据必须是相同的类型)。
现在,对于实施,您有两个选择:
- 使用显式
ConversionService
注册转换器:
@Component
public class EmployeeRequestConverter implements Converter<EmployeeRequest, EmployeeRequest> {
@Override
public EmployeeRequest convert(EmployeeRequest source) {
// Apply your decryption logic
}
}
为其他请求对象制作类似的转换器。
现在在您的控制器中:
public class MyController {
private ConversionService conversionService;
private MyService myService;
@RequestMapping(...)
public void aRequest(@RequestBody EmployeeRequest request) {
myService.execute(conversionService.convert(request, EmployeeRequest.class));
}
}
- 使用反射。
前提条件:您在加密字段上有 @Encrypted
注释。
与第一个解决方案不同,您不需要为每种类型的请求创建显式转换器。
@Service
public class DecryptionService {
public void <T> T decrypt(T input) {
Field[] fields = input.getClass().getDeclaredFields();
for (Field field : fields) {
Encrypted encrypted = field.getAnnotation(Encrypted.class);
if (encrypted != null) {
try{
field.setAccessible(true);
Object val = field.get(input);
// Base on @Encrypted annotation in your val, do the decryption
Object decryptedVal = ...;
field.set(input, decryptedVal);
} catch (Exception ex) {
}
}
}
}
}
现在您可以为您的控制器申请此服务了。
您可能想要缓存 Class.getDeclaredFields()
和 Class<?> -> @Encrypted fields
之间的映射以提高性能。