接口的参数进行验签处理

背景

需要与第三方对接接口。在对方的接口中存在几个异步通知,为了接口的安全性,需要对接口的参数进行验签处理。
为了方便大家对异步通知返回参数的处理,要将该验签功能进行统一封装,到时候大家只需要关注自己的业务逻辑即可。

方案1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

定义业务接口类
业务接口类包含两个方法:具体业务处理的类型;业务的具体处理方法。

public interface INotifyService {
/**
* 处理类型
*/
public String handleType();
/**
* 处理具体业务
*/
Integer handle(String notifyBody);

}
异步通知统一入口
@AllArgsConstructor
@RestController
@RequestMapping(value = "/notify")
public class NotifyController {
private IService service;

@PostMapping(value = "/receive")
public String receive(@RequestBody String body) {
//处理通知
Integer status = service.handle(body);
return "success";
}
}
在 Iservice 中做两个步骤:

在 spring 启动之后,收集所有的类型为 INotifyService的类并放入map中;
将参数进行处理转化,并验签处理;
private ApplicationContext applicationContext;
private Map<String,INotifyService> notifyServiceMap;

/**
* 启动加载
*/
@PostConstruct
public void init(){
Map<String,INotifyService> map = applicationContext.getBeansOfType(INotifyService.class);
Collection<INotifyService> services = map.values();
if(CollectionUtils.isEmpty(services)){
return;
}
notifyServiceMap = services.stream().collect(Collectors.toMap(INotifyService::handleType, x -> x));
}

@Override
public Map<String, INotifyService> getNotifyServiceMap() {
return notifyServiceMap;
}

@Override
public Integer handle(String body) {
//参数处理+验签逻辑
......

//获取具体的业务实现类
INotifyService notifyService=notifyServiceMap.get(notifyType);
Integer status=null;
if(Objects.nonNull(notifyService)) {
//执行具体业务
try {
status=notifyService.handle(JSON.toJSONString(requestParameter));
} catch (Exception e) {
e.printStackTrace();
}
}
//后续逻辑处理
......

return status;
}
业务具体实现
@Service
public class NotifySignServiceImpl implements INotifyService {

@Override
public String handleType() {
return "type_sign";
}

@Override
@Transactional
public Integer handle(String notifyBody) {
//具体的业务处理
......


小结
此方案提供统一的异步通知入口,把公共的参数处理和验签逻辑与业务逻辑剥离。
利用 java 动态加载类的特性,将实现类通过类型进行收集。
利用 java 多态的特性,通过不同的实现类来处理不同的业务逻辑。