如何使用XML实现多渠道接入网站的构架
来源:互联网 发布时间:2008-09-05 17:13:00
一.背景
在现在的网站中,接入的渠道是越来越多了,技术也是越来越先进,WAP, SMS,EMAIL, 传统的Web, Socket等等,如果连数据库和LDAP也算接入的话,那在设计之中需要扩展的空间要做到很好 很好,才保证在添加新的渠道情况下不需要更多的修改代码甚至不改代码的情况。但可能吗?我想也不可能,但有什么方式可以更好的解决这种多渠道接入的框架的完美性呢?
二.构架
【图一】
如图一所显示,在现有的所有接入都已经使用上的时候,设计者看的都眼花缭乱了,如果是为了凑份子,那这些程序怎么写都可以,而且也肯定可以实现,但维护起来就会比较痛苦,还是回到那个问题,怎么可以实现更完美呢?如图二显示:
【图二】
图二看起来象个八爪的章鱼,章鱼腿分别连接所有的接入渠道,进行连接所有这些渠道的核心就是这个章鱼的头XMLRouter,Router在此的作用是沟通所有渠道,实现数据的路由,争强系统在构架上的扩展性和灵活性,好处会很多很多。称呼为XMLRouter是因为如果不使用XML这种灵活而又规范的语言来做为数据传输的媒介,那Router的工作量也同样会成倍的增加,定义好XML的规范后将为以后的扩展带来很多好处。
三.思想和模式
XMLRouter的最初想法来自于计算机的主板和<
Services思想:为了能和Router进行沟通,在这些渠道接入时必须定义统一的接口,这里成为Services, 只要符合Services规范的程序就可以接入到Router并进行数据的路由.
Factory模式和Composite模式
XMLRouter在实际的设计中将采用Factory模式产生,Router由RouterFactory生产, 在投入使用时将放置于队列中,传递数据和接收数据以及返回数据都从队列中取相应的Router来调用,应用了Composite的模式.
四.XML配置文件
XML文件对于Router之中的使用分为两个部分, 第一个是Router的配置,如:
以下是引用片段:
<?xml version="1.0" ?>
<services>
<!-- database Service -->
<service name="database" type="database" class="com.web.service.DBService">
<connector
driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url="jdbc:microsoft:sqlserver://192.168.0.179:1433" user="test"
passwd="test" />
</service>
<!-- Web Service-->
<service name="web" type="web" class="com.web.service.WebService" >
<connector />
</service>
……
</services>
这是Router的配置文件, service节点代表需要接入的渠道, service节点包含connector子节点, 子节点的配置根据type来区分, 如果是database则包含url, user, passwd,driver等属性, 如果是socket则包含 port, maxthread等属性, 属性值可以根据自己的定义来配置.
另一种XML文件则是XML交易数据文件,用于在所有的services中传递数据,每个Services自己包涵一个相应的XML文件,比如webtrans.xml格式如下:
以下是引用片段:
<?xml version="1.0" ?>
<transaction>
<trans name="addDoc" service="database" method="insert">
<property name="createtime" type="timestamp"/>
<property name="creatorid" type="long"/>
<property name="doctypeid" type="int"/>
<property name="docstatusid" type="int"/>
</trans>
</transaction>
相应的dbtrans.xml格式如下
以下是引用片段:
<trans name="addDoc" table="TDOC_DOCS" method="insert">
<primarykey name="docid" />
<set>
<property name="createtime" type="timestamp"/>
<property name="creatorid" type="long"/>
<property name="doctypeid" type="int"/>
<property name="docstatusid" type="int"/>
</set>
</trans>
其余XML则可按这样的规则来定制
五.技术实现
RouterFactory
以下是引用片段:
package com.web.router;
import com.web.platform.Exception.RouterException;
import java.util.java/util/Hashtable.java.html" target="_blank">Hashtable;
以下是引用片段:
/**
* Router产生和清除的类
*/
public class RouterFactory
{
/**
* Router存储的树front
*/
private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null;
/**
* Router存储的树back
*/
private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null;
/**
* Router存储的树
*/
private static java/util/Hashtable.java.html" target="_blank">Hashtable QueueRouter = null;
/**
* 返回的XMLRouter
*/
public static XMLRouter instance = null;
/**
* Router的定义
*/
public static RouterDefine routerdefine = null;
/**
* Router的ID号
*/
public static long routeIndex = 0;
/**
* @roseuid 3F169C21027C
*/
public RouterFactory()
{
}
/**
* 初始化Hashtable和Vector
*/
public static void initFactory() throws java/lang/Exception.java.html" target="_blank">Exception
{
QueuePairFront = new java/util/Hashtable.java.html" target="_blank">Hashtable();
QueuePairBack = new java/util/Hashtable.java.html" target="_blank">Hashtable();
QueueRouter = new java/util/Hashtable.java.html" target="_blank">Hashtable();
initRouteDefine();
}
/**
* 初始化Route的设置
*
*/
private static void initRouteDefine() throws java/lang/Exception.java.html" target="_blank">Exception
{
if( routerdefine == null )
routerdefine = new RouterDefine();
routerdefine.loadRouterDef();
}
/**
* 返回实例
* @return com.web.router.XMLRouter
*/
public static XMLRouter getInstance(long index) throws RouterException
{
return (XMLRouter)QueueRouter.get(new java/lang/Long.java.html" target="_blank">Long(index));
}
/**
* 产生一个XMLRouter的实例
* @return com.web.router.XMLRouter
* @roseuid 3F1618A103BC
*/
public static XMLRouter popInstance() throws RouterException
{
routeIndex ++;
instance = new XMLRouter(routeIndex);
setDefine( instance );
QueueRouter.put(new java/lang/Long.java.html" target="_blank">Long(routeIndex), instance);
return instance;
}
/**
* 清空Hashtable,Vector等
* @roseuid 3F1618B203C1
*/
private static void freeResource() throws java/lang/Exception.java.html" target="_blank">Exception
{
QueuePairFront.clear();
QueuePairBack.clear();
QueueRouter.clear();
QueuePairFront = QueuePairBack = QueueRouter = null;
}
/**
* 清除实例
* @param instanceID
* @throws Exception
*/
public static void removeInstance(XMLRouter instance) throws java/lang/Exception.java.html" target="_blank">Exception
{
instance.clear();
QueueRouter.remove( new java/lang/Long.java.html" target="_blank">Long(instance.getIndex() ) ) ;
}
/**
* Method isNull.
* @return boolean
*/
public static boolean isNull()
{
……
return false;
}
}
XMLRouter
以下是引用片段:
package com.web.router;
import com.web.platform.Exception.RouterException;
import com.web.common.*;
import java.util.*;
import java.lang.reflect.java/lang/reflect/Method.java.html" target="_blank">Method;
import java.lang.reflect.java/lang/reflect/Constructor.java.html" target="_blank">Constructor;
/**
* @author keli
* @version 0.0.1
* 平台的关键,路由的类,每个Router将从RouterFactory里读取
* Router存储的树front,和back,routeIndex,目的是为了能在路由
* 之后可以清除申请的对象。
* Router可以实现同步和异步的功能.
*/
public class XMLRouter
{
/**
* Router存储的树front
*/
private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null;
/**
* Router存储的树back
*/
private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null;
/**
* 本router的index号码
*/
private long routeIndex = 0;
/**
* router的设置
*/
private RouterDefine define = null;
/**
* 用于判断是路由的起回点
*/
private java/lang/String.java.html" target="_blank">String action = "";
/**
*此变量只是用于在routeto方法中申请新的class
*/
private java/lang/String.java.html" target="_blank">String classname = "";
/**
*/
public XMLRouter(long index)
{
routeIndex = index;
}
/**
* 路由
* @throws Exception
* @roseuid 3F1616BD0186
*/
public void routing(Env env) throws RouterException, java/lang/Exception.java.html" target="_blank">Exception
{
/*如果为起点*/
if( action.equalsIgnoreCase( RouterConstant.CFG_FUNC_ROUTETO ) )
{
……
}
/*如果为返回点*/
else if( action.equalsIgnoreCase( RouterConstant.CFG_FUNC_ROUTEBACK ) )
{
……
}
/*否则为错误*/
else
throw new RouterException("Set Router action error.");
}
/**
* 读取本Router的id号.
* @return long
*/
public long getIndex()
{
return routeIndex;
}
/**
* 清除所有对象.
* @throws RouterException
*/
public void clear() throws RouterException
{
QueuePairFront.remove(new java/lang/Long.java.html" target="_blank">Long(routeIndex));
QueuePairBack.remove(new java/lang/Long.java.html" target="_blank">Long(routeIndex));
/*系统回收*/
java/lang/System.java.html" target="_blank">System.runFinalization();
}
/**
* 设置本Router的设置.
* @param def
* @throws RouterException
*/
public void setDefine(RouterDefine def) throws RouterException
{
define = def;
}
/**
* 设置action的值
* @param actionName
* @throws RouterException
*/
public void setAction( java/lang/String.java.html" target="_blank">String actionName )
{
action = actionName;
}
}
Service类
以下是引用片段:
package com.web.common;
import com.web.platform.Exception.RouterException;
/**
* Service的父类,abstract
*/
public abstract class RouteService
{
/**
*/
public RouteService()
{
}
/**
* routeTo方法,是交易的起点。
* @param env
* @throws RouterException
*/
public abstract void routeto(Env env) throws RouterException;
/**
* routeBack,交易的结束点,
* @param env
* @throws RouterException
*/
public abstract void routeback(Env env) throws RouterException;
/**
* routeaccept方法,是交易的接收点,也是routeto的接收函数,
* routeaccept为被动交易对象的主要处理函数
* @param env
* @throws RouterException
*/
public abstract void routeaccept(Env env) throws RouterException;
/**
* routing方法,是Service对外的接口函数
* @throws RouterException
*/
public abstract void routing() throws RouterException;
接下来则需要实现所有的Services的类了,这里就不做介绍了.
六.说明
这个Router到目前为止只能实现同步的交易, 暂时不支持异步的交易,但是由于对Router使用了Composite的模式设计的,实现异步交易也是可以扩展的,这里不做详细分析.
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 在机器上首次安装MySQL,操作系统是win7mysql 的安装文件是 zip 格式的,版本是5.7.17解压之后,安装步骤是1、首先找个文
- 在《 详解Python拼接字符串的七种方式 》这篇文章里,我提到过,字符串是程序员离不开的事情。后来,我看到了一个英文版本的说法:There
- 先介绍下什么是协程:协程,又称微线程,纤程,英文名Coroutine。协程的作用,是在执行函数A时,可以随时中断,去执行函数B,然后中断继续
- 前言:Python 是一种脚本语言,相比 C/C++ 这样的编译语言,在效率和性能方面存在一些不足。但是,有很多时候,Python 的效率并
- 本文实例讲述了Python装饰器原理与基本用法。分享给大家供大家参考,具体如下:装饰器:意义:在不能改变原函数的源代码,和在不改变整个项目中
- 匹配双字节字符(包括汉字在内): [^\x00-\xff] 应用:计算字符串的长度(一个双字节字符长度计2,ASCII
- nn.RNN(input_size, hidden_size, num_layers=1, nonlinearity=tanh, bias=
- #!/bin/bash#this is a script of mysql backup if [ ! -d /mydata/data1/b
- 本文实例讲述了Python实现的企业粉丝抽奖功能。分享给大家供大家参考,具体如下:一 代码def scode9(schoice): &nbs
- 微软在今天早上发布新的安全通告证实,一处远程执行代码漏洞影响到了整个SQL Server产品线。该漏洞的入侵代码在两周前已经被公布在互联网上
- 1. 前言但是对于很多人来说,首先编写一款 App 需要一定的移动端开发经验,其次还需要另外编写无障碍服务应用,如此显得有一定难度的本篇文章
- 如何使DIV居中,div垂直居中,div水平居中.这个问题在用CSS来设计网页的时候经常会遇到,如果用传统的表格来布局是很简单的,CSS里就
- 默认情况下,写在.vue组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。导致组件之间样式冲突的根本原因是:单页面应用程序中
- 本文实例讲述了Python找出list中最常出现元素的方法。分享给大家供大家参考,具体如下:假设一个list中保存着各种元素,需要统计每个元
- 触发器权限和所有权CREATE TRIGGER 权限默认授予定义触发器的表所有者、sysadmin 固定服务器角色成员以及 db_owner
- 目录[redis 调用Lua脚本](#redis 调用Lua脚本)[redis+lua 实现评分排行榜实时更新](#redis+lua 实现
- 引言https://github.com/go-chassis/go-chassis是一个微服务开发框架,而微服务开发框架带来的其中一个课题
- 前言因为Python的水平目前一直是处于能用阶段,平时写的脚本使用的Python的写法也比较的简单,没有写过稍微大一点的项目。对Python
- 1、将python打包好的exe解压为py文件,步骤如下: 下载pyinstxtractor.py文件2、下载地址:https://nchc
- 本文实例讲述了Python实现PS滤镜Fish lens图像扭曲效果。分享给大家供大家参考,具体如下:这里实现 PS 滤镜中的一种几何变换–