当前我有一项要求,我们的后端spring rest api将以加密的json格式接收数据(少数字段是加密的,而少数字段是纯文本) 然后应用解密,然后对数据应用一些业务逻辑,最后将数据存储到数据库中。
此解密逻辑正在重复多个服务实现方法。 因此,我们决定将解密逻辑与实际业务逻辑隔离。
我正在使用spring aop解密数据,并在解密之后 我要传递给服务层方法的对象。
但是我的服务层方法包含不同类型的对象作为参数
Ex:
processEmployee(EmployeeRequest request)
procesStudent(StudentRequest request)
我一直在寻找一种方法来动态改变 自己在同一对象字段上的数据(例如:EmployeeRequest,StudentRequest)
我尝试并遵循的第四步是以下方法。
1。引入了新的注释。
2。注释那些具有加密数据的字段。
3。检索所有带注释的字段。
4。每个字段数据我们将应用解密逻辑并 解密后的数据将再次注入同一字段
我正在寻找实现第四步的api吗?
是否有任何可用于动态执行的api 同一对象上的方法 或任何参考,请指出我。
答案 0 :(得分:2)
我的建议是不要对加密/解密的类都使用相同的POJO。它使将来的使用变得混乱(就像我收到了EmployeeRequest实例一样,是否已解密?),并且还限制了类型(因为您的加密/解密数据必须是同一类型)。
现在,对于实现,您有两种选择:
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
之间的映射以提高性能。