lyz880524 发表于 2020-8-25 19:55:55

AR动态切换数据源实现方案(jsp调用ar报表服务)

本帖最后由 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;
      
      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) == false || Tools.CheckValue(DynamicDataUtils.databases) == false || Tools.CheckValue(DynamicDataUtils.username) == false || Tools.CheckValue(DynamicDataUtils.password) == false)
            {
                DynamicDataUtils.init();
            }
            if (Tools.CheckValue(DynamicDataUtils.hostname) && Tools.CheckValue(DynamicDataUtils.databases) && Tools.CheckValue(DynamicDataUtils.username) && Tools.CheckValue(DynamicDataUtils.password))
            {
                connString = string.Format("Server={0};port={1};Database={2};Uid={3};Pwd={4};pooling=true;charset=utf8;Connect Timeout=36000;Allow User Variables=True", DynamicDataUtils.hostname.ToString(), DynamicDataUtils.port.ToString(), DynamicDataUtils.databases.ToString(), DynamicDataUtils.username.ToString(), DynamicDataUtils.password.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;
            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;
                        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;
                        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;
                if (key.StartsWith("#"))
                {
                  if (val == "")
                  {
                        sw.WriteLine(key);
                  }
                  else
                  {
                        sw.WriteLine(val);
                  }
                }
                else
                {
                  sw.WriteLine(key + "=" + val);
                }
            }
            sw.Close();
            fileStream.Close();
      }
    }

Lenka.Guo 发表于 2020-8-26 08:17:06

感谢宝贵的项目经验分享,对用户来说太有价值啦,点赞,并奖励3000金币~:hjyzw:

lyz880524 发表于 2020-8-26 09:45:19

互相学习

KearneyKang 发表于 2020-8-28 14:12:48

:)
页: [1]
查看完整版本: AR动态切换数据源实现方案(jsp调用ar报表服务)