找回密码
 立即注册

QQ登录

只需一步,快速开始

lyz880524 讲师达人认证

高级会员

153

主题

458

帖子

1167

积分

高级会员

积分
1167

微信认证勋章元老葡萄讲师达人

lyz880524 讲师达人认证
高级会员   /  发表于:2020-8-25 19:55  /   查看:2745  /  回复:3
本帖最后由 lyz880524 于 2020-8-25 20:02 编辑

ActiveReports后端代码实现动态切换数据源的方案整合(java中jsp调用ar报表)

前提:H5展示报表(jsp调用ar报表服务)

背景:ar产品的开发授权还是友好的,不像其他产品按部署收费。前期未做整体的规划,对每个客户都部署一套同样的报表系统。升级,维护较为繁琐。为了解决该问题,故修改ar的部署方案;

案例:
a企业购买我们的产品,我们要为a客户单独部署一套报表系统,b企业购买了,我们也要为b客户部署一套报表系统;
改造:每个版本部署一套报表系统,例如1.0版本报表系统部署一套,2.0版本报表系统部署一套
1.0的所有企业使用1.0报表的系统
2.0的所有企业使用2.0报表的系统

实现:
新增databases.properties文件,用于配置每个企业需要连接的数据库配置:具体配置如下

a1.websit.com.dbtype=mysql
a1.websit.com.hostname=192.168.1.1
a1.websit.com.database=db_a1
a1.websit.com.port=3306
a1.websit.com.user=root
a1.websit.com.password=123456


a2.websit.com.dbtype=mysql
a2.websit.com.hostname=192.168.12
a2.websit.com.database=db_a2
a2.websit.com.port=3306
a2.websit.com.user=root
a2.websit.com.password=123456



a1.websit.com 站点下 reportService 指向的是 a1.ar.websit.com/ReportWebService.asmx
a2.websit.com 站点下 reportService 指向的是 a2.ar.websit.com/ReportWebService.asmx

ar报表服务站点下 web.config 中 WebService 节点配置
publicURI="http://111.111.111.111:8800/" accessPoint="http://111.111.111.111:8800/ReportWebService.asmx"

Global.asax中增加读取databases.properties的方法
protected void Application_Start(object sender, EventArgs e)
{
DynamicDataUtils.init();
}


添加DynamicDataUtils类
public class DynamicDataUtils
    {
        #region
        /**
         * 数据库
         */
        public static Hashtable databases = new Hashtable();

        /**
         * 数据库类型
         */
        public static Hashtable dbtype = new Hashtable();

        /**
         * 数据库地址
         */
        public static Hashtable hostname = new Hashtable();

        /**
         * 端口号
         */
        public static Hashtable port = new Hashtable();

        /**
         * 账号
         */
        public static Hashtable username = new Hashtable();

        /**
         * 密码
         */
        public static Hashtable password = new Hashtable();
        #endregion

        public static void init()
        {
            try
            {
                databases.Clear(); dbtype.Clear(); hostname.Clear(); username.Clear(); password.Clear();
                PropertyOper p_db = new PropertyOper(HttpRuntime.AppDomainAppPath + "conf\\databases.properties");
                foreach(DictionaryEntry de in p_db)
                {
                    if(de.Key.ToString().Contains(".database"))
                    {
                        databases.Add(de.Key.ToString().Replace(".database", ""), de.Value);
                    }
                    else if (de.Key.ToString().Contains(".dbtype"))
                    {
                        dbtype.Add(de.Key.ToString().Replace(".dbtype", ""), de.Value);
                    }
                    else if (de.Key.ToString().Contains(".hostname"))
                    {
                        hostname.Add(de.Key.ToString().Replace(".hostname", ""), de.Value);
                    }
                    else if (de.Key.ToString().Contains(".port"))
                    {
                        port.Add(de.Key.ToString().Replace(".port", ""), de.Value);
                    }
                    else if (de.Key.ToString().Contains(".user"))
                    {
                        username.Add(de.Key.ToString().Replace(".user", ""), de.Value);
                    }
                    else if (de.Key.ToString().Contains(".password"))
                    {
                        password.Add(de.Key.ToString().Replace(".password", ""), de.Value);
                    }
                }
            }
            catch (Exception ex)
            {
                LogServer.WriteTextLog(LogType.Error, "DynamicDataUtils", "databases.properties文件初始读取错误"+ex.ToString(), DateTime.Now);
            }
        }
    }


.net 工程中 ReportWebService.asmx 增加配置如下:
public class ReportWebService : GrapeCity.ActiveReports.Web.ReportService
    {
        PageReport pageReport;
        PageDocument _pageDocument;
        string domainName;
        [WebMethod]
        protected override object OnCreateReportHandler(string reportPath)
        {
                     string domainName = HttpContext.Current.Request.Url.Host.Replace(".ar","");//这里拿到的是a1.websit.com  和 a2.websit.com
                     var pname = reportPath;
                     pageReport = (PageReport)base.OnCreateReportHandler("report/" + pname + ".rdlx");
                     pageReport.Report.Name = pname;
                     _pageDocument = new PageDocument(pageReport);
                    pageReport.Document.LocateDataSource += Document_LocateDataSource;
                    return pageReport;
              }
              private void Document_LocateDataSource(object sender, LocateDataSourceEventArgs args)
              {
                   Blls.DataSelect select = new Blls.DataSelect();
                   args.Data = select.GetData(args, domainName);//这里执行具体的sql查询和业务逻辑处理
              }
        }
}


连接数据库字符串获取方法

public static string GetConnectionString(string domainName)
        {
            string connString = string.Empty;
            if (Tools.CheckValue(DynamicDataUtils.hostname[domainName]) == false || Tools.CheckValue(DynamicDataUtils.databases[domainName]) == false || Tools.CheckValue(DynamicDataUtils.username[domainName]) == false || Tools.CheckValue(DynamicDataUtils.password[domainName]) == false)
            {
                DynamicDataUtils.init();
            }
            if (Tools.CheckValue(DynamicDataUtils.hostname[domainName]) && Tools.CheckValue(DynamicDataUtils.databases[domainName]) && Tools.CheckValue(DynamicDataUtils.username[domainName]) && Tools.CheckValue(DynamicDataUtils.password[domainName]))
            {
                connString = string.Format("Server={0};port={1};Database={2};Uid={3}wd={4};pooling=true;charset=utf8;Connect Timeout=36000;Allow User Variables=True", DynamicDataUtils.hostname[domainName].ToString(), DynamicDataUtils.port[domainName].ToString(), DynamicDataUtils.databases[domainName].ToString(), DynamicDataUtils.username[domainName].ToString(), DynamicDataUtils.password[domainName].ToString());
            }
            return connString;
        }


Tools.CheckValue 方法检测对象是否为null 或者 空

另外,贴上 PropertyOper.cs 该类用于对databases.properties的读取

public class PropertyOper : System.Collections.Hashtable
    {
        private string fileName = "";
        private ArrayList list = new ArrayList();
        public ArrayList List
        {
            get { return list; }
            set { list = value; }
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fileName">要读写的properties文件名</param>
        public PropertyOper(string fileName)
        {
            this.fileName = fileName;
            this.Load(fileName);
        }
        /// <summary>
        /// 重写父类的方法
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        public override void Add(object key, object value)
        {
            base.Add(key, value);
            list.Add(key);

        }

        public void Update(object key, object value)
        {
            base.Remove(key);
            list.Remove(key);
            this.Add(key, value);

        }
        public override ICollection Keys
        {
            get
            {
                return list;
            }
        }
        /// <summary>
        /// 加载文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        private void Load(string filePath)
        {
            char[] convertBuf = new char[1024];
            int limit;
            int keyLen;
            int valueStart;
            char c;
            string bufLine = string.Empty;
            bool hasSep;
            bool precedingBackslash;
            using (StreamReader sr = new StreamReader(filePath))
            {
                while (sr.Peek() >= 0)
                {
                    bufLine = sr.ReadLine();
                    limit = bufLine.Length;
                    keyLen = 0;
                    valueStart = limit;
                    hasSep = false;
                    precedingBackslash = false;
                    if (bufLine.StartsWith("#"))
                        keyLen = bufLine.Length;
                    while (keyLen < limit)
                    {
                        c = bufLine[keyLen];
                        if ((c == '=' || c == ':') & !precedingBackslash)
                        {
                            valueStart = keyLen + 1;
                            hasSep = true;
                            break;
                        }
                        else if ((c == ' ' || c == '\t' || c == '\f') & !precedingBackslash)
                        {
                            valueStart = keyLen + 1;
                            break;
                        }
                        if (c == '\\')
                        {
                            precedingBackslash = !precedingBackslash;
                        }
                        else
                        {
                            precedingBackslash = false;
                        }
                        keyLen++;
                    }
                    while (valueStart < limit)
                    {
                        c = bufLine[valueStart];
                        if (c != ' ' && c != '\t' && c != '\f')
                        {
                            if (!hasSep && (c == '=' || c == ':'))
                            {
                                hasSep = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                        valueStart++;
                    }
                    string key = bufLine.Substring(0, keyLen);
                    string values = bufLine.Substring(valueStart, limit - valueStart);
                    if (key == "")
                        key += "#";
                    while (key.StartsWith("#") & this.Contains(key))
                    {
                        key += "#";
                    }
                    if (values.Length > 0)
                    {
                        this.Add(key, values);
                    }
                }
            }
        }
        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="filePath">要保存的文件的路径</param>
        public void Save()
        {
            string filePath = this.fileName;
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            FileStream fileStream = File.Create(filePath);
            StreamWriter sw = new StreamWriter(fileStream);
            foreach (object item in list)
            {
                String key = (String)item;
                String val = (String)this[key];
                if (key.StartsWith("#"))
                {
                    if (val == "")
                    {
                        sw.WriteLine(key);
                    }
                    else
                    {
                        sw.WriteLine(val);
                    }
                }
                else
                {
                    sw.WriteLine(key + "=" + val);
                }
            }
            sw.Close();
            fileStream.Close();
        }
    }

评分

参与人数 1金币 +3000 收起 理由
Lenka.Guo + 3000 赞一个!

查看全部评分

3 个回复

倒序浏览
Lenka.Guo讲师达人认证 悬赏达人认证
超级版主   /  发表于:2020-8-26 08:17:06
沙发
感谢宝贵的项目经验分享,对用户来说太有价值啦,点赞,并奖励3000金币~
回复 使用道具 举报
lyz880524讲师达人认证
高级会员   /  发表于:2020-8-26 09:45:19
板凳
互相学习
回复 使用道具 举报
KearneyKang讲师达人认证 悬赏达人认证
超级版主   /  发表于:2020-8-28 14:12:48
地板
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部