前段时间有一个业务需求,需要做一个中转的服务,对外部请求的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/
至此,完成。