java 单机接口限流处理方案
346
2022-09-06
Java使用策略模式实现聚石塔接口调用的问题
背景
有个业务需求对接淘宝开放平台。这里面涉及到了聚石塔,聚石塔是阿里系的一款产品,可以理解为一个服务器,淘宝开发平台一些较为敏感的数据,会要求发布进聚石塔。外部需要调用要通过走奇门网关。奇门中心也有详细描述。
研究了一下文档发现,需要写两套代码:
1、第一套适配聚石塔接口,发布在聚石塔内;
2、更新最新的SDK,放在第二套代码,通过SDK里面的奇门调用
写代码之前还需要在奇门中心配置好自定义api场景,并且规定好统一的入参以及响应
重点!!聚石塔内,一个appKey在一个场景内,只能授权配置一个路由。而且用springmvc接收入参不能用@RequestBody,只能用HttpServletRequest。
/**
* 聚石塔
* @param request
* @return
*/
@RequestMapping("tower")
public String tower(HttpServletRequest request) {
// 逻辑
return "";
}
我们需要调用很多接口,每个接口的url,入参都不同,这怎么办呢?
我的处理方式是从统一的入参入手,定义了三个参数:
1)接口类型:type,用来判断走哪个url
2)授权参数:authParams,用来接收不同的授权入参
3)接口请求参数:reqParams,用来接收不同接口的不同入参
相当于一个controller方法要判断很多个接口
/**
* 聚石塔
* @param request
* @return
*/
@RequestMapping("tower")
public String tower(HttpServletRequest request) {
String type = request.getParameter("type");
if ("1".equals(type)) {
// 具体方法
}
if ("2".equals(type)) {
// 具体方法
}
if ("3".equals(type)) {
// 具体方法
}
if ("4".equals(type)) {
// 具体方法
}
return "";
}
解决方法
为了避免多重判断,而且有更好的扩展性,首选了策略模式来实现。
1、首先,定义一个策列模式接口,我这边主要以type来判断
public interface MethodStrategy {
String selectMethod(String type, HttpServletRequest request);
}
2、然后有多少个接口就写多少个实现类,我这边拿一个实现类为例子
public class SmsCreateSignNahttp://meClient implements MethodStrategy {
@Override
public String selectMethod(String type, HttpServletRequest request) {
// 获取授权参数
String authStr = request.getParameter("authParams");
// 获取接口请求参数
String reqStr = request.getParameter("reqParams");
// 这里写此接口具体的逻辑
}
}
3、创建一个策略类的工厂,相当于总共记录有多少种类别。这里用strategyMap来存储。key建议用枚举类管理起来,代表接口方法,奇门调用时传type值时保持一致,value则为具体的实现类。
public class StrategyFactory {
private static StrategyFactory factory = new StrategyFactory();
private static Map strategyMap = new ConcurrentHashMap<>();
static {
// 短信相关,key建议用枚举类管理起来,代表接口方法,奇门调用时传type值时保持一致,value则为具体的实现类
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_SINGLE.getValue(), new SmsSendSingleClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_BATCH.getValue(), new SmsSendBatchClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_OAID.getValue(), new SmsSendOaIdClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_QUERY.getValue(), new SmsSendQueryClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_CREATE_URL.getValue(), new SmsCreateUrlClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_TEMPLATE_CODE_CREATE.getValue(), new SmsCreateTemplateCodeClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_TEMPLATE_CODE_QUERY.getValue(), new SmsTemplateCodeQueryClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_SIGN_NAME_QUERY.getValue(), new SmsSignNameQueryClient());
strategyMap.put(TaoBaoEnums.SmsMethods.SEND_SIGN_NAME_CREATE.getValue(), new SmsCreateSignNameClient());
}
private StrategyFactory() {
}
public MethodStrategy getMethod(String type) {
return (MethodStrategy) strategyMap.get(type);
}
public static StrategyFactory getFactory() {
return factory;
}
}
4、接着配置策略模式上下文
public class MethodContext {
/**
* 方法选择
* @param type
* @param request
* @return
*/
public String selectMethod(String type, HttpServletRequest request) {
MethodStrategy methodStrategy = StrategyFactory.getFactory().getMethod(type);
return methodStrategy.selectMethod(type, request);
}
}
5、最后,在controller方法
/**
* 聚石塔内 一个appKey在一个场景内(短信是一个场景,订单是一个场景)只能授权配置一个路由,因此用一个接口以及策列模式接收一个场景内所有的淘宝api接口
*
* @param requesACmfBt 聚石塔入参用request接收,此接口的参数对应为:
* type(接口类型。string)、
* authParams(授权参数。json的string:appKey,appSecret,sessionKey)、
* reqParams(接口请求参数,每个接口不同,具体需依据淘宝api接口。json的string)
* @return 此接口响应类,规定json的string:sub_message:Illegal request、 flag:failure、sub_code:sign-check-failure
*/
@RequestMapping("tower")
public String tower(HttpServletRequest request) {
String type = request.getParameter("type");
MethodContext methodContext = new MethodContext();
return methodContext.selectMethod(type, request);
}
写好所有实现类代码后,即可发布聚石塔
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~