个人主页:金鳞踏雨
个人简介:大家好,我是金鳞,一个初出茅庐的Java小白
目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作
我的博客:这里是CSDN,是我学习技术,总结知识的地方。希望和各位大佬交流,共同进步 ~
前言
前一段时间,跟着视频学习了策略模式,总结如下:
【23种设计模式】策略模式(State Pattern)_金鳞踏雨的博客-CSDN博客https://harmony.blog.csdn.net/article/details/131078118这几天公司的项目中正好使用到了策略模式!由于项目中经常需要调HTTP请求,所以使用策略模式来处理不同的HTTP请求。
策略模式
简单来说,就是为了解决多重 if 的问题,优化代码结构
环境(Context)/ 上下文:环境是策略模式的核心,它持有一个策略对象的引用,并在需要执行特定算法时,调用策略对象的方法。环境类负责将客户端的请求委派给具体的策略对象。
抽象策略(Strategy):抽象策略定义了策略类的公共接口,它可以是一个接口或抽象类。它声明了策略类应该实现的方法,以便环境类能够通过统一的接口调用不同的策略。
具体策略(Concrete Strategy):具体策略是抽象策略的具体实现,它实现了策略接口定义的方法,并封装了具体的算法逻辑。在不同的具体策略中,算法的实现可以有所不同。
策略模式实现通用的HTTP接口
1. 抽象策略(Strategy)
public abstract class AbstractXXXInterface {
private static final Logger logger = Logger .getLogger("XXX");
protected Context ctx;
protected String otherJsonParam;
protected int type;
/** 查询接口配置信息的sql */
private static final String querySql = "SELECT interfaceUrl, isOpen, typeLabel from T_RH_InterfaceConfig where interfaceType = %s";
/** 单据编号 */
protected String billNumber;
/** 接口配置信息 */
private InterfaceConfigEntity info;
private String result;
/** 请求方式:get、post */
protected String httpMethodType;
private JSONObject jsonObject;
protected JSONObject otherParam;
private boolean isCheckOpen = true;
public AbstractXXXInterface setIsCheckOpen(boolean isCheckOpen) {
this.isCheckOpen = isCheckOpen;
return this;
}
protected abstract void initData();
public AbstractXXXInterface call() throws Exception {
if (StringUtils.isNotBlank(otherJsonParam)) {
otherParam = JSONObject.parseObject(otherJsonParam);
}
// 校验
validator();
if (!isCall()) {
return this;
}
initData();
// 获取接口信息
info = getInterfaceInfo();
if (info == null) {
throw new BOSException("接口信息为空");
}
if (isCheckOpen && !isOpen(info.getIsOpen())) {
logger.error("接口:【" + info.getInterfaceLabel() + "】未开启");
setResult("接口:【" + info.getInterfaceLabel() + "】未开启");
return this;
}
// 设置接口参数
info.setParamJson(createParamJson());
// 调用接口
jsonObject = HttpClientNewUtil.doHttp(ctx, info, httpMethodType);
// 处理响应结果
callBack();
return this;
}
protected boolean isCall() throws Exception {
return true;
}
/**
* 通用校验,可以重写该方法实现自己的校验
*/
protected void validator() throws Exception {
if (StringUtils.isBlank(billNumber)) {
logger.error("接口:【" + info.getInterfaceLabel() + "】单据编号为空");
throw new BOSException("单据编号不能为空");
}
}
/**
* 执行sql获取接口信息
*/
private InterfaceConfigEntity getInterfaceInfo() throws Exception {
try {
IRowSet rowSet = DbUtil.executeQuery(ctx, String.format(querySql, type));
while (rowSet.next()) {
InterfaceConfigEntity info = new InterfaceConfigEntity();
info.setInterfaceUrl(rowSet.getString("interfaceUrl"));
info.setIsOpen(rowSet.getInt("isOpen"));
info.setInterfaceLabel(rowSet.getString("typeLabel"));
return info;
}
} catch (Exception e) {
logger.error("sql: " + type + "执行异常.", e);
throw new Exception(e.getMessage());
}
return null;
}
/**
* 处理响应结果
*/
protected void callBack() throws Exception {
JSONObject result = getJsonObject();
if (result == null) {
logger.error("单据【" + billNumber + "】响应结果为空");
return;
}
if (isSuccess(result.getString("code"))) {
successAfter(result);
} else {
failAfter(result);
}
}
/**
* 成功后调用
*/
protected abstract void successAfter(JSONObject result) throws Exception;
/**
* 失败后调用
*/
protected abstract void failAfter(JSONObject result) throws Exception;
/**
* 根据具体单据创建请求参数
*/
protected abstract String createParamJson() throws Exception;
/**
* 判断是否开启:1-开启,返回true
*/
private boolean isOpen(int isOpen) {
return CommonUtils.convertBoolean(isOpen);
}
protected boolean isSuccess(String code) {
return XXXConstant.InterfaceReturnCode.SUCCESSE.equals(code) ||
XXXConstant.InterfaceReturnCode.SUCCESSE1.equals(code) ||
XXXConstant.InterfaceReturnCode.SUCCESSE2.equals(code);
}
/**
* getter、setter方法
*/
protected void setXXX(String XXX) {
this.XXX= XXX;
}
public String getXXX() {
return XXX;
}
}
2. 抽象工厂
public class XXXFactory {
private XXXFactory() {
}
public static AbstractXXXInterface getStrategy(int type) {
if (XXXConstant.InterfaceType.TYPE1 == type) {
return new DEMO1();
} else if (XXXConstant.InterfaceType.TYPE2 == type) {
return new DEMO2();
} else if (...) {
return ...;
} else {
return null;
}
}
}
3. 具体策略(Concrete Strategy)
public class DEMO1 extends AbstractXXXInterface {
private static Logger logger = Logger.getLogger("XXX");
@Override
protected String createParamJson() throws BOSException, SQLException {
// 拼接请求报文(body)
return null;
}
@Override
protected void failAfter(JSONObject result) throws BOSException,
SQLException {
// 调用接口失败的处理逻辑,处理响应
setResult("同步失败");
}
@Override
protected void initData() {
this.httpMethodType = CommonConstant.HttpType.POST;
this.type = XXXConstant.InterfaceType.TYPE1;
}
@Override
protected void successAfter(JSONObject result) throws BOSException,
SQLException {
// 调用接口成功的处理逻辑,处理响应
setResult("同步成功");
}
}
4. HTTP工具类
/**
* HTTP工具类
*/
public class HttpClientNewUtil {
private static final Logger logger = Logger.getLogger("XXX");
public static JSONObject doHttp(Context ctx, InterfaceConfigEntity info, String type) {
String url = info.getInterfaceUrl();
String token = "";
try {
if (isUrlEmpty(url)) {
logger.error("接口地址为空");
return null;
}
logger.error("start call interface: " + info.getInterfaceLabel());
logger.error("The paramJson is: " + info.getParamJson());
CloseableHttpClient httpClient = createClient(url);
if (CommonConstant.HttpType.POST.equals(type)) {
return doPost(ctx, httpClient, url, info, token);
} else if (CommonConstant.HttpType.GET.equals(type)) {
return doGet(ctx, httpClient, url, info, token);
}
} catch (Exception e) {
logger.error("访问接口失败,接口地址为:" + url, e);
}
return null;
}
private static JSONObject doPost(Context ctx, CloseableHttpClient httpClient, String url,
InterfaceConfigEntity info, String token) throws IOException {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("source", "99");
httpPost.setHeader("site", "1");
// 设置Token头部
httpPost.setHeader("token", getToken(ctx));
if(info.getParamJson() != null) {
StringEntity entity = new StringEntity(info.getParamJson(), "UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
return parseResult(httpClient.execute(httpPost), info);
}
private static JSONObject doGet(Context ctx, CloseableHttpClient httpClient, String url,
InterfaceConfigEntity info, String token) throws IOException {
Map<String, String> params = JSONObject.parseObject(info.getParamJson(), Map.class);
List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
for (Map.Entry<String, String> entry : params.entrySet()) {
String value = entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
}
}
url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, "UTF-8"));
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("source", "99");
httpGet.setHeader("site", "1");
// 设置Token头部
httpGet.setHeader("token", getToken(ctx));
return parseResult(httpClient.execute(httpGet), info);
}
private static JSONObject parseResult(CloseableHttpResponse response, InterfaceConfigEntity info) throws IOException {
logger.error("response:" + response);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String resultJson = EntityUtils.toString(response.getEntity(), "utf-8");
logger.error(info.getInterfaceLabel() + " response: " + resultJson);
response.close();
return JSONObject.parseObject(resultJson);
}
return null;
}
/**
* 创建HttpClient客户端
*/
@SuppressWarnings("deprecation")
private static CloseableHttpClient createClient(String url) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
if (url.startsWith("https")) {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
httpClientBuilder.setSSLSocketFactory(sslsf);
} catch (Exception e) {
logger.error("创建HTTPS客户端异常", e);
}
}
return httpClientBuilder.build();
}
/**
* 判断url是否为空:为空返回true
*/
private static boolean isUrlEmpty(String url) {
return StringUtils.isBlank(url);
}
/**
* 获取token
*/
private static String getToken(Context ctx) {
String token = null;
try {
String sql = "select interfaceUrl from T_RH_InterfaceConfig where interfaceType = 14;";
IRowSet rs = DbUtil.executeQuery(ctx, sql);
rs.next();
// 构造获取Token的请求
HttpPost tokenRequest = new HttpPost(rs.getString("interfaceUrl"));
tokenRequest.setHeader("Content-Type", "application/json");
// 设置请求参数,如用户名和密码
JSONObject requestBody = new JSONObject();
requestBody.put("account", "eas");
requestBody.put("password", "o6H95Utzv9GKzvx9+P45Zw==");
StringEntity entity = new StringEntity(requestBody.toJSONString());
entity.setContentType("application/json");
tokenRequest.setEntity(entity);
// 发送请求并解析响应
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(tokenRequest);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String responseBody = EntityUtils.toString(response.getEntity());
JSONObject responseJson = JSONObject.parseObject(responseBody);
// 提取Token字段
int code = responseJson.getIntValue("code");
if (code == 1000) {
JSONObject data = responseJson.getJSONObject("data");
token = data.getString("token");
}
}
// 关闭资源
response.close();
httpClient.close();
} catch (Exception e) {
logger.error("获取Token失败", e);
}
return token;
}
}
文章到这里就结束了,如果有什么疑问的地方,可以在评论区指出~
希望能和大佬们一起努力,诸君顶峰相见
再次感谢各位小伙伴儿们的支持!!!