http接口服务方结合策略模式实现总结
在項(xiàng)目中,我們經(jīng)常會(huì)使用到http+xml的接口,而且不僅僅的是一個(gè),可能會(huì)有多個(gè)http的接口需要實(shí)時(shí)的交互.但是http接口的接收消息的公共部分是一樣的,只有每個(gè)接口的報(bào)文解析和返回報(bào)文是不同的,此時(shí)考慮到把變化和不變化的隔離出來(lái),采取用策略模式,把公共的部分代碼抽取隔離出來(lái),每個(gè)http接口的不同的處理邏輯單獨(dú)自己處理,這樣也方便了后期的修改和擴(kuò)展,可以很方便的修改單獨(dú)的接口處理邏輯和添加新的http接口到項(xiàng)目中使用,而不用修改以前的設(shè)計(jì).下面就http+xml接口的接收采用簡(jiǎn)單的策略模式實(shí)現(xiàn):
項(xiàng)目的基礎(chǔ):SSH架構(gòu)
首先實(shí)現(xiàn)BaseReceiveHttpIntfAction 基類(lèi),實(shí)時(shí)的接收?qǐng)?bào)文動(dòng)作和返回結(jié)果報(bào)文動(dòng)作:具體的解析邏輯和獲取返回報(bào)文邏輯抽取隔離出去:
/*** 〈一句話(huà)功能簡(jiǎn)述〉<br>* 〈功能詳細(xì)描述〉 http 接收接口基類(lèi)實(shí)現(xiàn) 父類(lèi)實(shí)現(xiàn)為prototype 不是單例的* * 基于策略模式 后面增加子類(lèi)接收實(shí)現(xiàn)的方法 請(qǐng)參照:CrmReceiveHttpIntfAction的實(shí)現(xiàn)* * @author lilin* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本] (可選)*/ @Controller @Scope(value = "prototype") public abstract class BaseReceiveHttpIntfAction extends BasicAction {/***/private static final long serialVersionUID = -4667071743433536439L;private IHttpMessageHandle httpMessageHandle;/*** * 功能描述: <br>* 〈功能詳細(xì)描述〉用于 子類(lèi) 注入父類(lèi)屬性* * @param httpMessageHandle* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本](可選)*/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 解析接收?qǐng)?bào)文:");SAXReader sb = new SAXReader();String returnStr = null;try {Document document = sb.read(inputStream);logger.info(document.asXML());// 保存報(bào)文信息Map<String, Object> map = httpMessageHandle.handleMessage(document);// 拼接返回報(bào)文returnStr = httpMessageHandle.getResponseMsg(map, document);logger.info("@@ 報(bào)文解析成功!");} catch (DocumentException e) {logger.info("@@HttpClient 解析報(bào)文出錯(cuò)!", e);}logger.info("@@ 返回報(bào)文 : " + returnStr);writeResponse(returnStr, response);return null;}/*** * 功能描述: <br>* 〈功能詳細(xì)描述〉* * @param respXML* @param response* @throws IOException* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本](可選)*/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);}}}}}然后:規(guī)定好子類(lèi)需要注入的公共接口IHttpMessageHandle, 接口定義需要解析報(bào)文的解析方法,以及獲取放回報(bào)文的方法:
/*** 〈一句話(huà)功能簡(jiǎn)述〉<br>* 〈功能詳細(xì)描述〉* * @author lilin* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本] (可選)*/ public interface IHttpMessageHandle {/*** * 功能描述: <br>* 〈功能詳細(xì)描述〉處理接收到的報(bào)文信息* * @param document* @return* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本](可選)*/Map<String, Object> handleMessage(Document document);/*** * 功能描述: <br>* 〈功能詳細(xì)描述〉獲取需要返回的報(bào)文信息* * @param map* @param document* @return* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本](可選)*/String getResponseMsg(Map<String, Object> map, Document document);}然后:實(shí)現(xiàn)實(shí)際的處理報(bào)文信息的類(lèi):CrmHttpMessageHandle 實(shí)時(shí)處理CRM系統(tǒng)發(fā)送的xml報(bào)文信息,實(shí)時(shí)組裝需要返回的報(bào)文信息:
/*** 〈一句話(huà)功能簡(jiǎn)述〉<br>* 〈功能詳細(xì)描述〉* * @author lilin* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本] (可選)*/ @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);// 設(shè)置返回值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 保存報(bào)文信息成功!");} else {res.put("reFlag", "E");res.put("errorMessage", "報(bào)文頭有問(wèn)題");}return res;}最后:實(shí)現(xiàn)實(shí)際的接收?qǐng)?bào)文信息的子類(lèi)action:繼承基類(lèi),實(shí)時(shí)注入父類(lèi)的接口實(shí)現(xiàn),最終提供給客戶(hù)端的url:http://lilin.com/lilin-web/crmReceiveHttpIntfAction.do
/*** 〈一句話(huà)功能簡(jiǎn)述〉<br>* 〈功能詳細(xì)描述〉* * @author lilin* @see [相關(guān)類(lèi)/方法](可選)* @since [產(chǎn)品/模塊版本] (可選)*/ @Controller public class CrmReceiveHttpIntfAction extends BaseReceiveHttpIntfAction {/***/private static final long serialVersionUID = -104341558961432099L;@Resourceprivate IHttpMessageHandle crmHttpMessageHandle;@PostConstructpublic void injectHttpMessageHandle() {super.setHttpMessageHandle(crmHttpMessageHandle);} }這樣,簡(jiǎn)單的http+xml報(bào)文+策略模式的實(shí)現(xiàn),就完成了.后期需要擴(kuò)展新的接口接口使用,只要僅僅實(shí)現(xiàn)自己的
1,接收子類(lèi)<參考CrmReceiveHttpIntfAction?>
2,消息處理類(lèi):<參考CrmHttpMessageHandle>
3,提供最終的服務(wù)方的url給客戶(hù)端調(diào)用即可;
?
轉(zhuǎn)載于:https://www.cnblogs.com/lilin0719/p/5247452.html
總結(jié)
以上是生活随笔為你收集整理的http接口服务方结合策略模式实现总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: WinCE 自由拼音输入法的测试
- 下一篇: java servlet上传centos