本帖最后由 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();
}
}
|