http接口服务方结合策略模式实现总结
在项目中,我们经常会使用到http+xml的接口,而且不仅仅的是一个,可能会有多个http的接口需要实时的交互.但是http接口的接收消息的公共部分是一样的,只有每个接口的报文解析和返回报文是不同的,此时考虑到把变化和不变化的隔离出来,采取用策略模式,把公共的部分代码抽取隔离出来,每个http接口的不同的处理逻辑单独自己处理,这样也方便了后期的修改和扩展,可以很方便的修改单独的接口处理逻辑和添加新的http接口到项目中使用,而不用修改以前的设计.下面就http+xml接口的接收采用简单的策略模式实现:
项目的基础:SSH架构
首先实现BaseReceiveHttpIntfAction 基类,实时的接收报文动作和返回结果报文动作:具体的解析逻辑和获取返回报文逻辑抽取隔离出去:
/*** 〈一句话功能简述〉<br>* 〈功能详细描述〉 http 接收接口基类实现 父类实现为prototype 不是单例的* * 基于策略模式 后面增加子类接收实现的方法 请参照:CrmReceiveHttpIntfAction的实现* * @author lilin* @see [相关类/方法](可选)* @since [产品/模块版本] (可选)*/ @Controller @Scope(value = "prototype") public abstract class BaseReceiveHttpIntfAction extends BasicAction {/***/private static final long serialVersionUID = -4667071743433536439L;private IHttpMessageHandle httpMessageHandle;/*** * 功能描述: <br>* 〈功能详细描述〉用于 子类 注入父类属性* * @param httpMessageHandle* @see [相关类/方法](可选)* @since [产品/模块版本](可选)*/public void setHttpMessageHandle(IHttpMessageHandle httpMessageHandle) {this.httpMessageHandle = httpMessageHandle;}public String doBusiness() {InputStream inputStream = null;try {inputStream = request.getInputStream();} catch (IOException e1) {logger.error("IOException: ", e1);}logger.info("@@HttpClient 解析接收报文:");SAXReader sb = new SAXReader();String returnStr = null;try {Document document = sb.read(inputStream);logger.info(document.asXML());// 保存报文信息Map<String, Object> map = httpMessageHandle.handleMessage(document);// 拼接返回报文returnStr = httpMessageHandle.getResponseMsg(map, document);logger.info("@@ 报文解析成功!");} catch (DocumentException e) {logger.info("@@HttpClient 解析报文出错!", e);}logger.info("@@ 返回报文 : " + returnStr);writeResponse(returnStr, response);return null;}/*** * 功能描述: <br>* 〈功能详细描述〉* * @param respXML* @param response* @throws IOException* @see [相关类/方法](可选)* @since [产品/模块版本](可选)*/private void writeResponse(String respXML, HttpServletResponse response) {OutputStream out = null;try {byte[] data = respXML.getBytes("UTF-8");out = response.getOutputStream();out.write(data);} catch (IOException e) {logger.error("Write response error: ", e);} finally {if (out != null) {try {out.flush();out.close();} catch (IOException e) {logger.error("IOException: ", e);}}}}}
然后:规定好子类需要注入的公共接口IHttpMessageHandle, 接口定义需要解析报文的解析方法,以及获取放回报文的方法:
/*** 〈一句话功能简述〉<br>* 〈功能详细描述〉* * @author lilin* @see [相关类/方法](可选)* @since [产品/模块版本] (可选)*/ public interface IHttpMessageHandle {/*** * 功能描述: <br>* 〈功能详细描述〉处理接收到的报文信息* * @param document* @return* @see [相关类/方法](可选)* @since [产品/模块版本](可选)*/Map<String, Object> handleMessage(Document document);/*** * 功能描述: <br>* 〈功能详细描述〉获取需要返回的报文信息* * @param map* @param document* @return* @see [相关类/方法](可选)* @since [产品/模块版本](可选)*/String getResponseMsg(Map<String, Object> map, Document document);}
然后:实现实际的处理报文信息的类:CrmHttpMessageHandle 实时处理CRM系统发送的xml报文信息,实时组装需要返回的报文信息:
/*** 〈一句话功能简述〉<br>* 〈功能详细描述〉* * @author lilin* @see [相关类/方法](可选)* @since [产品/模块版本] (可选)*/ @Service public class CrmHttpMessageHandle implements IHttpMessageHandle {private Logger logger = Logger.getLogger(CrmHttpMessageHandle.class);@Resourceprivate LowPriceTaskService lowPriceTaskService;@Overridepublic String getResponseMsg(Map<String, Object> map, Document document) {logger.info("CrmHttp Get ResponseMsg:");printLogByEntry(map);Document doc = DocumentHelper.createDocument();// MbfService 拼接Element mbfService = DocumentHelper.createElement("MbfService");doc.add(mbfService);Element output1 = DocumentHelper.createElement("output1");mbfService.add(output1);// MbfHeader 拼接Element mbfHeader = DocumentHelper.createElement("MbfHeader");output1.add(mbfHeader);PriceCommonService.addElement(mbfHeader, "ServiceCode", (String) map.get("ServiceCode"));PriceCommonService.addElement(mbfHeader, "Operation", (String) map.get("Operation"));PriceCommonService.addElement(mbfHeader, "AppCode", (String) map.get("AppCode"));PriceCommonService.addElement(mbfHeader, "UId", (String) map.get("UId"));// ServiceResponse 拼接Element serviceResponse = DocumentHelper.createElement("ServiceResponse");mbfHeader.add(serviceResponse);PriceCommonService.addElement(serviceResponse, "Status", null);PriceCommonService.addElement(serviceResponse, "Code", null);PriceCommonService.addElement(serviceResponse, "Desc", null);// MbfBody 拼接Element mbfBody = DocumentHelper.createElement("MbfBody");output1.add(mbfBody);PriceCommonService.addElement(mbfBody, "reFlag", (String) map.get("reFlag"));PriceCommonService.addElement(mbfBody, "errorMessage", (String) map.get("errorMessage"));logger.info("CrmHttp Final ResponseMsg:" + doc.asXML());return doc.asXML();}@Overridepublic Map<String, Object> handleMessage(Document document) {logger.info("CrmHttp Start HandleMessage:");Map<String, Object> res = new HashMap<String, Object>();LowPriceTask task = new LowPriceTask();Element root = document.getRootElement();Element outElement = root.element("input1");Element mbfHeader = outElement.element("MbfHeader");String serviceCode = mbfHeader.elementTextTrim("ServiceCode");res.put("ServiceCode", serviceCode);logger.info("## ServiceCode : " + serviceCode);String operation = mbfHeader.elementTextTrim("Operation");res.put("Operation", operation);logger.info("## operation : " + operation);String appCode = mbfHeader.elementTextTrim("AppCode");res.put("AppCode", appCode);logger.info("## appCode : " + appCode);String uId = mbfHeader.elementTextTrim("UId");res.put("UId", uId);logger.info("## uId : " + uId);// 设置返回值if (!StringUtils.isEmpty(serviceCode) && !StringUtils.isEmpty(operation)) {task.setMsg(document.asXML());task.setScanNum(0);task.setScanResult("F");task.setStoreTime(DateUtils.getDate2());lowPriceTaskService.saveTask(task);res.put("reFlag", "S");res.put("errorMessage", "S");logger.info("@@HttpClient 保存报文信息成功!");} else {res.put("reFlag", "E");res.put("errorMessage", "报文头有问题");}return res;}
最后:实现实际的接收报文信息的子类action:继承基类,实时注入父类的接口实现,最终提供给客户端的url:http://lilin.com/lilin-web/crmReceiveHttpIntfAction.do
/*** 〈一句话功能简述〉<br>* 〈功能详细描述〉* * @author lilin* @see [相关类/方法](可选)* @since [产品/模块版本] (可选)*/ @Controller public class CrmReceiveHttpIntfAction extends BaseReceiveHttpIntfAction {/***/private static final long serialVersionUID = -104341558961432099L;@Resourceprivate IHttpMessageHandle crmHttpMessageHandle;@PostConstructpublic void injectHttpMessageHandle() {super.setHttpMessageHandle(crmHttpMessageHandle);} }
这样,简单的http+xml报文+策略模式的实现,就完成了.后期需要扩展新的接口接口使用,只要仅仅实现自己的
1,接收子类<参考CrmReceiveHttpIntfAction >
2,消息处理类:<参考CrmHttpMessageHandle>
3,提供最终的服务方的url给客户端调用即可;
转载于:https://www.cnblogs.com/lilin0719/p/5247452.html
http接口服务方结合策略模式实现总结相关推荐
- 接口进阶:接口子类实例化和策略模式
文章目录 几种类型的实例化 示例生成CS 0501: 实例化场景 策略模式案例 设计谜题 几种类型的实例化 抽象类 - 不可以直接实例化 同样纯抽象类 - 接口,也不可以直接实例化 使用虚方法的类(有 ...
- java对接支付宝微信银联_经典设计模式之策略模式【如何重构聚合支付平台,对接【支付宝,微信,银联支付】】(示例代码)...
写在前面:设计模式源于生活,而又高于生活! 为什么要使用设计模式重构代码 使用设计模式可以重构整体架构代码.提高代码复用性.扩展性.减少代码冗余问题. Java高级工程师装逼的技能! 什么是策略模式 ...
- 小白写了一堆if-else,大神实在看不下去了,竟然用策略模式直接摆平了
这里涉及到一个关键词:策略模式,那么到底什么是策略模式呢?本文就来好好给大家讲讲策略模式,大家可以带着如下几个问题来阅读本文: 如何通过策略模式优化业务逻辑代码(可以根据自己从事的工作思考) 使用策略 ...
- 设计模式之策略模式(Strategy)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- php 策略模式实现原理,php 策略模式原理与应用深入理解
php 策略模式原理与应用深入理解,策略,可以用,接口,简单,算法 php 策略模式原理与应用深入理解 易采站长站,站长之家为您整理了php 策略模式原理与应用深入理解的相关内容. 本文实例讲述了ph ...
- 『设计模式』再谈Macdonald的汉堡口味--策略模式
23种设计模式+额外常用设计模式汇总 (持续更新) 类的划分原则 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类. 策略模式 1.定 ...
- Java设计模式6:策略模式
策略模式 策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包 ...
- 策略模式(Strategy 模式)
一.概述 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 二.结构 策略 ...
- 支付服务代码设计(策略模式,可扩展,接入方便)
最近一直在深入学习一些知识,整理出一些东西一直没有时间写出来,后续会慢慢总结一下写在博客上,对于博客还是不想专门写知识点,总结和提升终究是为了自己,写出来的博客为了让别人看的好,更为了自己的成长和记录 ...
最新文章
- Ubuntu修改IP地址和MAC地址
- 【MASHIII调制器】MASHIII调制器的Simulink建模与仿真
- 2013豆瓣校园招聘研发类笔试题
- 【转】线段树题目 汇总 讲解(by not only success)
- oracle php
- php写的squid验证辅助器
- android native.js,Android Native与JS通信互调
- php 变量文件间传递,同一文件的两个JS函数之间如何传变量?
- 【程序设计】变量的作用域
- 蚂蚁金服 Service Mesh 大规模落地系列 - 运维篇
- tf.image.crop_and_resize()使用
- Greg and Array CodeForces 296C 差分数组
- 学校计算机编程用的什么软件,电脑编程软件都有哪些
- 怎么使用小爱同学音响_小爱同学语音唤醒功能怎么设置,小爱同学音箱的优缺点是什么...
- 广搜算法之翻转棋子游戏
- 如何在你朋友面前伪装黑客3(程序代码)
- 手机浏览器 打开 APP,APP 嵌套在了浏览器里,网页跳转app问题
- vs为什么打了断点不断_2019年丹麦羽毛球公开赛焦点对阵:林丹VS塞帕拉内斯 石宇奇 VS 马克卡尔尤B...
- 【车联网原型系统|三】树莓派设计+模拟基站程序
- Cubieboard1 引导安装 Debian 系统