将报表中sql和参数信息输出到指定文件

有客户需要将报表名称、报表数据集sql、报表参数值、访问报表时间、登录人信息都输出到指定文件,这样可以追踪敏感报表被访问的情况。

分析

需求中提到的登录人信息、访问报表时间以及报表名称都可以直接获得,而数据集sql和参数信息需要计算报表后得到。所以这些需求可以放到计算监听类中实现。

Sql可以通过SQLDataSetConfig得到,报表参数值可以通过Context拿到,其他的信息先放到request中,然后在计算监听类中使用内置的request对象获得。最后将取到的所有信息通过javaIO输出到文件中。

实现

准备任意带有参数的浏览式报表,在发布报表的jsp中加入计算监听类:calculateListener=”listener.CalcListenerWriteSql”

CalcListenerWriteSql类关键部分:

1、 通过DataSetConfig获取数据集名,SQLDataSetConfig获取数据集sql

DataSetMetaData dsmd = report.getDataSetMetaData();//获取数据集元对象

int dsNum = dsmd.getDataSetConfigCount();//获取数据集个数

for (int i = 0; i < dsNum; i++) {//遍历所有数据集

DataSetConfig dsc = dsmd.getDataSetConfig(i);

String dsName = dsc.getName();//取数据集名

SQLDataSetConfig sdsc = (SQLDataSetConfig) dsmd.getDataSetConfig(i);

String sql = sdsc.getSQL();//取数据集sql

}

2、 通过ParamMetaDataContext获取参数值

ParamMetaData pmd = report.getParamMetaData();//获取参数元对象

Param param = null;

String paramName = null;

String ctxParamValue = null;

DateFormat df = new SimpleDateFormat(“yyyy-MM-dd”);//日期格式

for (int i = 0; i < pmd.getParamCount(); i++) {

param = pmd.getParam(i);

if (param != null) {

paramName = (String) param.getParamName();//获得参数名

Object obj = context.getParamValue(paramName);//通过参数名,获取参数值(Object类型)

if (obj != null && !“”.equals(obj)) {

if (obj instanceof Date) {// 日期类型不能toString

ctxParamValue = df.format(obj);

} else {

ctxParamValue = obj.toString();

}

}

}

}

3、 最后通过IO输出txt文件

File f = new File(realPath + File.separator + “sql_param.log”);

BufferedWriter output = new BufferedWriter(new FileWriter(f));

output.write(s1);

output.close();

总结

本例获取的数据集sql是数据集的原始sql,如:ds1=SELECT EMPLOYEE.EMPID,EMPLOYEE.EMPNAME,EMPLOYEE.BIRTHDAY,EMPLOYEE.SEX,EMPLOYEE.DEGREE,EMPLOYEE.BONUS FROM EMPLOYEE WHERE (EMPLOYEE.EMPNAME like ? or ? is null) ;参数值和sql是分离的。

而文本文件的读写效率较低,所以本例适合只记录某些重要报表信息,且文件的读写频率较小的情况。