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 SmsCreateSignNameClient 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 request 聚石塔入參用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);
    }

 寫好所有實現類代碼後,即可發佈聚石塔

到此這篇關於Java使用策略模式實現聚石塔接口調用的文章就介紹到這瞭,更多相關Java聚石塔接口調用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: