在项目中,我们经常会使用到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接口服务方结合策略模式实现总结相关推荐

  1. 接口进阶:接口子类实例化和策略模式

    文章目录 几种类型的实例化 示例生成CS 0501: 实例化场景 策略模式案例 设计谜题 几种类型的实例化 抽象类 - 不可以直接实例化 同样纯抽象类 - 接口,也不可以直接实例化 使用虚方法的类(有 ...

  2. java对接支付宝微信银联_经典设计模式之策略模式【如何重构聚合支付平台,对接【支付宝,微信,银联支付】】(示例代码)...

    写在前面:设计模式源于生活,而又高于生活! 为什么要使用设计模式重构代码 使用设计模式可以重构整体架构代码.提高代码复用性.扩展性.减少代码冗余问题. Java高级工程师装逼的技能! 什么是策略模式 ...

  3. 小白写了一堆if-else,大神实在看不下去了,竟然用策略模式直接摆平了

    这里涉及到一个关键词:策略模式,那么到底什么是策略模式呢?本文就来好好给大家讲讲策略模式,大家可以带着如下几个问题来阅读本文: 如何通过策略模式优化业务逻辑代码(可以根据自己从事的工作思考) 使用策略 ...

  4. 设计模式之策略模式(Strategy)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  5. php 策略模式实现原理,php 策略模式原理与应用深入理解

    php 策略模式原理与应用深入理解,策略,可以用,接口,简单,算法 php 策略模式原理与应用深入理解 易采站长站,站长之家为您整理了php 策略模式原理与应用深入理解的相关内容. 本文实例讲述了ph ...

  6. 『设计模式』再谈Macdonald的汉堡口味--策略模式

    23种设计模式+额外常用设计模式汇总 (持续更新) 类的划分原则 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类. 策略模式 1.定 ...

  7. Java设计模式6:策略模式

    策略模式 策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包 ...

  8. 策略模式(Strategy 模式)

    一.概述 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 二.结构 策略 ...

  9. 支付服务代码设计(策略模式,可扩展,接入方便)

    最近一直在深入学习一些知识,整理出一些东西一直没有时间写出来,后续会慢慢总结一下写在博客上,对于博客还是不想专门写知识点,总结和提升终究是为了自己,写出来的博客为了让别人看的好,更为了自己的成长和记录 ...

最新文章

  1. Ubuntu修改IP地址和MAC地址
  2. 【MASHIII调制器】MASHIII调制器的Simulink建模与仿真
  3. 2013豆瓣校园招聘研发类笔试题
  4. 【转】线段树题目 汇总 讲解(by not only success)
  5. oracle php
  6. php写的squid验证辅助器
  7. android native.js,Android Native与JS通信互调
  8. php 变量文件间传递,同一文件的两个JS函数之间如何传变量?
  9. 【程序设计】变量的作用域
  10. 蚂蚁金服 Service Mesh 大规模落地系列 - 运维篇
  11. tf.image.crop_and_resize()使用
  12. Greg and Array CodeForces 296C 差分数组
  13. 学校计算机编程用的什么软件,电脑编程软件都有哪些
  14. 怎么使用小爱同学音响_小爱同学语音唤醒功能怎么设置,小爱同学音箱的优缺点是什么...
  15. 广搜算法之翻转棋子游戏
  16. 如何在你朋友面前伪装黑客3(程序代码)
  17. 手机浏览器 打开 APP,APP 嵌套在了浏览器里,网页跳转app问题
  18. vs为什么打了断点不断_2019年丹麦羽毛球公开赛焦点对阵:林丹VS塞帕拉内斯 石宇奇 VS 马克卡尔尤B...
  19. 【车联网原型系统|三】树莓派设计+模拟基站程序
  20. Cubieboard1 引导安装 Debian 系统

热门文章

  1. SharePoint At Work----Hyperlinks in the Data View Web Part
  2. list转datatable
  3. [导入]关于谭浩强[上]
  4. ThreadLocal应用与原理分析
  5. TWAIN协议学习笔记
  6. windows server 2008解决无法PING通问题
  7. 使用maven生成scala项目的目录结构
  8. Android 应用 之路 天气预报(五)
  9. 【Unity】6.8 Quaternion类(四元数)
  10. 绘画 某种字体 以某种折行规则 最后画出的text有多大