策略模式深度实践——通用的HTTP接口调用

news/2024/4/29 5:50:15/文章来源:https://blog.csdn.net/weixin_43715214/article/details/131507380

个人主页:金鳞踏雨

个人简介:大家好,我是金鳞,一个初出茅庐的Java小白

目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作

我的博客:这里是CSDN,是我学习技术,总结知识的地方。希望和各位大佬交流,共同进步 ~

前言

前一段时间,跟着视频学习了策略模式,总结如下:

【23种设计模式】策略模式(State Pattern)_金鳞踏雨的博客-CSDN博客icon-default.png?t=N5K3https://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");@Overrideprotected String createParamJson() throws BOSException, SQLException {// 拼接请求报文(body)        return null;}@Overrideprotected void failAfter(JSONObject result) throws BOSException,SQLException {// 调用接口失败的处理逻辑,处理响应setResult("同步失败");		}@Overrideprotected void initData() {this.httpMethodType = CommonConstant.HttpType.POST;this.type = XXXConstant.InterfaceType.TYPE1; }@Overrideprotected 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() {// 信任所有@Overridepublic 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;}
}

文章到这里就结束了,如果有什么疑问的地方,可以在评论区指出~

希望能和大佬们一起努力,诸君顶峰相见

再次感谢各位小伙伴儿们的支持!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_325536.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HNU-小学期工训-STC-B案例测试作业

对于一些案例&#xff0c;这里列举一些 流水灯 八位数码管动态扫描 八位数码管流水灯(有BSP版本) 八位数码管滚动显示(有BSP版本) 可变亮度的数码管显示(有BSP版本) 扫描频率可改变的电子钟 按键消抖计数(有BSP版本) 三按键测试(有BSP版本) 霍尔磁场检测(有BSP版本) 数…

kubectl详解之声明式管理方法

目录 一、声明式管理方法二、资源配置清单的管理2.1 查看资源配置清单2.1 修改资源配置清单并应用2.1.1 离线修改2.1.2 在线修改 一、声明式管理方法 适合于对资源的修改操作 声明式资源管理方法依赖于资源配置清单文件对资源进行管理 资源配置清单文件有两种格式&#xff1a;…

【C++11】lambda表达式详解

目录 1.lambda引入 2.语法 3.捕捉列表详解 [ ] 不捕获任何外部变量 [] 捕获父作用域的所有变量的值&#xff0c;只读不可以修改 [&]捕获父作用域的所有变量的引用&#xff0c;可修改捕获的变量 [val] 只捕获指定的变量值&#xff0c;不可以修改 [&val] 只捕获外…

【中间件-Openjob】高性能任务调度框架Openjob简介及快速搭建

介绍基础基础信息任务调度框架对比 特性高可靠高性能定时调度分布式计算延迟任务工作流程权限管理告警监控跨语言 安装访问docker-compose安装在线访问 总结 介绍 一款分布式高性能任务调度框架&#xff0c;支持多种定时任务、延时任务、工作流设计、轻量级分布式计算、无限水平…

谈谈NLP中 大语言模型LLM的 思维链 Chain-of-Thought(CoT)

Chain-of-Thought(CoT) 1.介绍 在过去几年的探索中&#xff0c;业界发现了一个现象&#xff0c;在增大模型参数量和训练数据的同时&#xff0c;在多数任务上&#xff0c;模型的表现会越来越好。因而&#xff0c;现有的大模型LLM&#xff0c;最大参数量已经超过了千亿。 然而…

kong-dashboard安装

简介 kong-dashboard提供了UI界面操作和查看kong&#xff0c;可以进行api、consumers、plugins操作 官网&#xff1a;https://hub.docker.com/r/pgbi/kong-dashboard/ 安装 联网安装 [slviewDEMO:~]$ docker search kong-dashboard INDEX NAME …

【VB6|第19期】vb6通过COM组件操作Excel

日期&#xff1a;2023年7月3日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

【elementplus】解决el-table开启show-overflow-tooltip后,tooltip的显示会被表格边框遮挡的问题

如图所示&#xff1a; 原因&#xff1a; 1. el-table没有设置高度&#xff1b;2.就是被遮住了 解决&#xff1a; 方法一&#xff1a;给el-table设置高度 方法二: .el-table {overflow: visible !important;}如果不想给el-table设置高度&#xff0c;就直接使用方法二解决即可

MyBatisPlus基础知识

一、MyBatisPlus 1.MyBatisPlus入门案例与简介 这一节我们来学习下MyBatisPlus的入门案例与简介&#xff0c;这个和其他课程都不太一样&#xff0c;其他的课程都是先介绍概念&#xff0c;然后再写入门案例。而对于MyBatisPlus的学习&#xff0c;我们将顺序做了调整&#xff0…

初级保育员专业知识生活管理考试题库及答案

​本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题…

JAVA开发( 腾讯云消息队列 RocketMQ使用总结 )

一、问题背景 之所以需要不停的总结是因为在java开发过程中使用到中间件实在太多了&#xff0c;久久不用就会慢慢变得生疏&#xff0c;有时候一个中间很久没使用&#xff0c;可能经过了很多版本的迭代&#xff0c;使用起来又有区别。所以还是得不断总结更新。最近博主就是在使用…

jenkins的环境搭建

jenkins 环境 安装 我之前使用war安装、安装比较简单、就是jenkins的 对应的插件不能下载下来、后来发现是版本的问题、使用docker-compose 安装、jenkins安装 插件很容易安装下来 1、安装jdk 解压jdk 配置环境变量 #set java environment JAVA_HOME/usr/local/jdk1.8.0_281…

blender 之点云渲染(论文渲图)

blender 之点云渲染&#xff08;论文渲图&#xff09; 一、导入点云1.新建2.导入点云3.位置移动&放大缩小 二、Geometry Nodes实体化点云1.新建节点2.实体化 三、给实体化点云添加材质四、设置渲染引擎更换为Cycles。 五、对准视角1.新建一个球2.创建相机视角跟踪3.将uv球挪…

二、Spring Cloud Eureka 简介、快速入门

注册发现中心 Eureka 来源于古希腊词汇&#xff0c;意为“发现了”。在软件领域&#xff0c; Eureka 是 Netflix 在线影片公司开源的一个服务注册与发现的组件&#xff0c;和其他 Netflix 公司的服务组件&#xff08;例如负载均衡、熔断器、网关等&#xff09; 一起&#xff0…

LLM prompt提示构造案例

参考&#xff1a; https://github.com/PlexPt/awesome-chatgpt-prompts-zh 吴恩达 prompt工程应用&#xff1a; https://www.bilibili.com/video/BV1No4y1t7Zn prompt构造案例代码 prompt """文本分类任务&#xff1a;将一段用户给外卖服务的评论进行分类…

初级保育员专业知识配合教育考试题库及答案

本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题练…

Linux基础笔记

已经有很长很长一段时间没有更新帖子了&#xff0c;一眨眼2023 已经过半&#xff0c;这些日子里&#xff0c;有太多太多事情要做了&#xff0c;今年只更新了几篇&#xff0c;这几天刚好有空&#xff0c;浅浅更新一篇叭&#xff01;~~~ 首先&#xff0c;Linux是一种开源的操作系…

手搓GPT系列之 - 通过理解LSTM的反向传播过程,理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式,配超多图帮助理解(下篇)

本文承接上篇上篇在此和中篇中篇在此&#xff0c;继续就Sepp Hochreiter 1997年的开山大作 Long Short-term Memory 中APPENDIX A.1和A.2所载的数学推导过程进行详细解读。希望可以帮助大家理解了这个推导过程&#xff0c;进而能顺利理解为什么那几个门的设置可以解决RNN里的梯…

git push origin masterEverything up-to-date解决方法

按住这个看一下很简单的问题&#xff0c;我在网上看了很多就是没找到能用的&#xff0c;最后找到了这个看起来写的很简单的一个文章&#xff0c;但他写的真的有用。 出现的问题 解决步骤第一步 git add . 第二步 git commit -m “message” 第三步 git push origin master…

PyTorch示例——ResNet34模型和Fruits图像数据

PyTorch示例——ResNet34模型和Fruits图像数据 前言导包数据探索查看数据集构建构建模型 ResNet34模型训练绘制训练曲线 前言 ResNet34模型&#xff0c;做图像分类数据使用水果图片数据集&#xff0c;下载见Kaggle Fruits Dataset (Images)Kaggle的Notebook示例见 PyTorch——…