springboot+策略模式

前段時間有一個業務需求,需要做一箇中轉的服務,對外部請求的url進行判斷跳轉到內部對應的請求方法裏面,其中涉及到各種if else。後來考慮到if else太多不好,又有新的規則加入。於是,我就想到了策略模式:

SendBankController.java:

package com.thsoft.tra.controller;

import com.thsoft.tra.service.SendBankService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @Author: EagleLin
 * @Date: 2019/9/31 16:25
 * @Version 1.0
 * @Title:
 * @Description:
 */
@SuppressWarnings("all")
@RestController
@RequestMapping("SpecialAccount/Bank")
@CrossOrigin
@Slf4j
public class SendBankController {

    @Resource
    private SendBankService sendBankService;

    @PostMapping(value = "{partName}",produces = "application/json;charset=UTF-8")
    public String sendBank(@PathVariable String partName, @RequestBody String data, HttpServletRequest request) throws Exception {
        String result =  sendBankService.sendBank(partName, data, request);
        return result;
    }
}

SendBankService.java:

package com.thsoft.tra.service;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @Author: EagleLin
 * @Date: 2019/9/4 9:06
 * @Version 1.0
 * @Title:
 * @Description:
 */
public interface SendBankService {

    String sendBank(String partName, String data, HttpServletRequest request) throws IOException, CloneNotSupportedException;
    
}

SendBankServiceImpl.java:

package com.thsoft.tra.service.impl;

import com.thsoft.tra.service.SendBankService;
import com.thsoft.tra.util.HttpSendTools;
import com.thsoft.tra.util.SimpleContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @Author: EagleLin
 * @Date: 2019/9/4 9:07
 * @Version 1.0
 * @Title:
 * @Description:
 */
@Slf4j
@Service
public class SendBankServiceImpl implements SendBankService {

    @Autowired
    private SimpleContext simpleContext;

    @Override
    public String sendBank(String partName, String data, HttpServletRequest request) throws IOException, CloneNotSupportedException {
        return simpleContext.getResource(partName, data);
    }
}

SimpleContext.java:

package com.thsoft.tra.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: EagleLin
 * @Date: 2019/9/5 23:30
 * @Version 1.0
 * @Title:
 * @Description:
 */
@Service
public class SimpleContext {

    @Autowired
    private final Map<String, Strategy> strategyMap = new ConcurrentHashMap<>();

    public SimpleContext(Map<String, Strategy> strategyMap) {
        this.strategyMap.clear();
        strategyMap.forEach((k, v)-> this.strategyMap.put(k, v));
    }

    public String getResource(String poolId, String data) throws IOException, CloneNotSupportedException {
        return strategyMap.get(poolId).getVpcList(poolId, data);
    }

}

AdditionalSpecialAccountInfo.java:

package com.thsoft.tra.util;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @Author: EagleLin
 * @Date: 2019/9/5 23:23
 * @Version 1.0
 * @Title:
 * @Description:
 */
@Component("AdditionalSpecialAccountInfo")
public class AdditionalSpecialAccountInfo implements Strategy {

    private String host;
    @Value("${sendBank.address.ip}")
    public void setHost(String host){
        this.host = host;
    }
    
    @Resource
    private HttpSendTools httpSendTools;

    @Override
    public String getVpcList(String id, String data) throws IOException, CloneNotSupportedException {
        return httpSendTools.sendByPost(host + id, data, "send");
    }
}

Strategy.java:

package com.thsoft.tra.util;

import java.io.IOException;

/**
 * @Author: EagleLin
 * @Date: 2019/9/5 23:15
 * @Version 1.0
 * @Title:
 * @Description:
 */
public interface Strategy {

    String getVpcList(String id, String data) throws IOException, CloneNotSupportedException;

}

HttpSendTools.java:

package com.thsoft.tra.util;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.jboss.logging.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @Author: EagleLin
 * @Date: 2019/8/21 14:16
 * @Version 1.0
 * @Title:
 * @Description:
 */
@SuppressWarnings("all")
@Service
public class HttpSendTools {

    @Resource
    private GetAccessToken getAccessToken;

    private static final Logger log = Logger.getLogger(HttpSendTools.class);

    private static RequestConfig requestConfig;

    static {
        RequestConfig.Builder builder = RequestConfig.custom();
        builder.setConnectTimeout(60 * 1000);
        builder.setSocketTimeout(120 * 1000);
        builder.setConnectionRequestTimeout(60 * 1000);
        requestConfig = builder.build();
    }

    public String sendByPost(String stringUrl,String json, String type) throws IOException, CloneNotSupportedException {

        //銀行請求專戶系統需要access_token,需要放在header裏面,有效期爲2小時
        String access_token = "";
        if(type.equals("send")){
            access_token = "null";
        }else if(type.equals("return")){
            access_token = getAccessToken.getToken();
        }

        String url = stringUrl;

        CloseableHttpClient client = HttpClients.createDefault();

        // 第一步,創建HttpPost對象
        HttpPost httpPost = new HttpPost(url);

        httpPost.setConfig(requestConfig);

        // 設置HTTP POST請求參數用json裝填參數
        StringEntity stringEntity = new StringEntity(json, "utf-8");
        // 設置請求編碼
        stringEntity.setContentEncoding("utf-8");
        // 設置請求類型
        stringEntity.setContentType("application/json");

        //認證token
        httpPost.addHeader("access-token", access_token);

        // CloseableHttpResponse httpResponse = null;
        HttpResponse httpResponse = null;
        try {

            // 設置httpPost請求參數,設置參數到請求對象中
            httpPost.setEntity(stringEntity);

            httpResponse = client.execute(httpPost);
            String result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 第三步,使用getEntity方法活得返回結果
                return result;
            } else {
                log.error("sendRequest error: " + url + ",response:" + result);
                return result;
            }
        } catch (Exception e) {
            log.error("sendRequest error: " + url);
            log.error(e.getMessage(), e);
        } finally {
            if (client != null) {
                client.close();
            }
            if (httpResponse != null) {
                // httpResponse.close();
            }
            if (httpPost != null) {
                httpPost.clone();
            }
        }
        return null;
    }
}

application.yml:

server:
  port: port
sendBank:
  address:
    ip: http://localhost:port/SpecialAccount/Bank/

至此,完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章