此文档说明如何在Smartbi中实现自定义JavaeBean示例。
在项目的使用过程中,有一些数据不能直接从关系或者多维数据源中获取,可能需要从另外一些途径获取又或者需要一些特殊的处理。
Smartbi中的基于关系数据源的数据集、多维数据集和多维分析都无法完成此功能,因此提供了Java查询二次开发接口允许项目进行定制开发。 为了应对这种需求,Smartbi提供了一个可以根据需要扩充的Java查询方式,可以根据实际情况开发来满足您的需求。
本方案是在Smartbi中添加自定义的Java查询类,并使Smartbi正确的展示数据的过程。 下面讲解一下具体的实现步骤:
- 按照开发扩展包的说明,新建扩展包项目MyJavaQueryProj,如果是使用cmd脚本创建,配置如下图:

- 解压smartbi.war到临时目录
- 将临时目录中的/WEB-INF/lib/smartbi-FreeQuery.jar、smartbi-Common.jar等smartbi依赖包复制到扩展包项目MyJavaQueryProj的lib-compile目录,并添加该目录下所有jar为项目的依赖包(如果要添加的jar不是smartbi.war中的jar,但是自定义javabean需要使用,则需要将jar包复制到MyJavaQueryProj的src/web/META-INF/lib目录,该目录下的jar在打包扩展包时将一同打包)
- 在MyJavaQueryProj项目中新建一个类com.proj.MyJavaQuery,并实现接口
IJavaQueryData.ISimpleData
(该接口声明返回该类返回的数据量比较少,Smartbi会自动读取所有数据并支持计算字段、排序、聚合、条件的功能),
注:如果java查询不需要配置项,其init方法和loadConfigs 需要定义空方法实现:

- 编译项目,运行/MyJavaQueryProj/build.xml将项目打包为扩展包MyJavaQueryProj.ext,如下图
注:Eclipse等IDE编译用的JDK必须与Smartbi服务器运行的JDK使用同一个版本

- 执行后刷新MyJavaQueryProj项目,可以看到新增一个dist目录,目录下MyJavaQueryProj.ext文件就是生成的扩展包

- 按照扩展包部署的方法,部署MyJavaQueryProj.ext到smartbi
- 重启smartbi应用服务器
- 在【定制管理】→【数据管理】的“数据源”节点右键新建Java数据源
- “Java数据源”上右键“新建Java查询对象”在类名中输入正确的Java查询实现类全名(如com.proj.MyJavaQuery)并点击获取默认配置,其中默认配置是调用java查询代码中的getConfigs()方法获取的,获取后可自定义修改配置

修改文件名配置为E:\test.csv

- 点击获取参数与结果集并保存

- 保存后就可以在【定制管理】→【数据集定义】的“Java查询”中使用对应的Java查询对象新建Java查询,拖动Java查询字段到表达式编辑器,然后保存Java查询


- 保存Java查询到指定目录后,可以基于java查询新建分析


这里是一个CSV文件查询的例子源码(是自定义javabean示例,只是刚好实现的就是CSV文件查询场景)。
package com.proj;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import smartbi.freequery.metadata.IJavaQueryData;
import smartbi.freequery.metadata.JavaQueryConfig;
import smartbi.freequery.metadata.JavaQueryOutputField;
import smartbi.freequery.metadata.JavaQueryParameter;
import smartbi.freequery.querydata.CellData;
import smartbi.freequery.querydata.GridData;
import smartbi.net.sf.json.JSONObject;
import smartbi.util.StringUtil;
import smartbi.util.ValueType;
public class MyJavaQuery implements IJavaQueryData.ISimpleData {
private Map<String, JavaQueryConfig> configs = new LinkedHashMap<String, JavaQueryConfig>();
private BufferedReader reader;
private List<JavaQueryOutputField> outputFields;
private int currentLine;
public MyJavaQuery() {
// 增加一个名称为FileName的配置项
addConfig("FileName", "文件名", "给定一个文件名", "test.csv", true);
addConfig("Encoding", "编码", "编码方式", "GBK", true);
}
/**
* 获取Java查询需要的配置信息
*/
public List<JavaQueryConfig> getConfigs() {
return new ArrayList<JavaQueryConfig>(configs.values());
}
/**
* 添加一个配置项
*
* @param name
* 名称
* @param alias
* 别名
* @param desc
* 描述
* @param defaultValue
* 默认值
* @param notNull
* 是否允许为空
*/
private void addConfig(String name, String alias, String desc,
String defaultValue, boolean notNull) {
JavaQueryConfig p = new JavaQueryConfig();
p.setName(name);
p.setAlias(alias);
p.setDesc(desc);
p.setValue(defaultValue);
p.setNotNull(notNull);
configs.put(name, p);
}
/**
* 从保存的字符串中恢复配置信息
*
* @param configStr
* 配置字符串
*/
public void loadConfigs(String configStr) {
if (StringUtil.isNullOrEmpty(configStr))
return;
JSONObject obj = JSONObject.fromString(configStr);
configs.get("FileName").setValue(
obj.has("FileName") ? obj.getString("FileName") : null);
configs.get("Encoding").setValue(
obj.has("Encoding") ? obj.getString("Encoding") : null);
}
/**
* 保存配置信息
*
* @return 返回配置字符串
*/
public String saveConfigs() {
JSONObject json = new JSONObject();
for (JavaQueryConfig config : configs.values())
json.put(config.getName(), config.getValue());
return json.toString();
}
/**
* 设置配置信息
*
* @param key
* 名称
* @param value
* 配置值
*/
public void setConfigValue(String key, String value) {
configs.get(key).setValue(value);
}
/**
* 设置配置信息
*/
public void setConfigValues(Map<String, String> configValues) {
for (Entry<String, String> config : configValues.entrySet())
configs.get(config.getKey()).setValue(config.getValue());
}
/**
* 根据配置信息初始化Java查询对象
*/
public void init() {
try {
outputFields = new ArrayList<JavaQueryOutputField>();
File file = new File(configs.get("FileName").getValue());
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
if (configs.get("Encoding").getValue().toLowerCase().equals("utf-8")) {
byte[] headData = new byte[3];
fis.read(headData, 0, 3);
if (headData[0] != (byte) 0xef || headData[1] != (byte) 0xbb || headData[2] != (byte) 0xbf) {
fis.close();
fis = new FileInputStream(file);
}
}
reader = new BufferedReader(new InputStreamReader(fis, configs.get("Encoding").getValue()));
String titleLine = reader.readLine();
String[] fields = titleLine == null ? "".split(",") : titleLine.split(",");
for (String str : fields) {
JavaQueryOutputField f = new JavaQueryOutputField();
f.setId(str);
f.setName(str);
f.setAlias(str);
if (str.equals(StringUtil.getLanguageValue("Value1"))) {
f.setDataType(ValueType.DOUBLE);
} else {
f.setDataType(ValueType.STRING);
}
outputFields.add(f);
}
}
currentLine = 0;
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
} catch (FileNotFoundException e) {
throw new IllegalArgumentException(e);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 关闭Java查询对象,关闭必要的资源
*/
public void close() {
try {
if (reader != null) {
reader.close();
reader = null;
}
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 返回参数对象
*/
public List<JavaQueryParameter> getParameters() {
return new ArrayList<JavaQueryParameter>();
}
/**
* 设置参数值
*/
public void setParameterValue(String id, String value, String displayValue) {
}
/**
* 返回Java查询的输出字段
*/
public List<JavaQueryOutputField> getOutputFields() {
return outputFields;
}
/**
* 获取指定行的数据
*/
public GridData getGridData(int from, int count) {
try {
if (currentLine > from) {
if (reader != null) {
reader.close();
FileInputStream fis = new FileInputStream(configs.get("FileName").getValue());
if (configs.get("Encoding").getValue().toLowerCase().equals("utf-8")) {
byte[] headData = new byte[3];
fis.read(headData, 0, 3);
if (headData[0] != (byte) 0xef || headData[1] != (byte) 0xbb || headData[2] != (byte) 0xbf) {
fis.close();
fis = new FileInputStream(configs.get("FileName").getValue());
}
}
reader = new BufferedReader(new InputStreamReader(fis, configs.get("Encoding").getValue()));
reader.readLine();
}
currentLine = 0;
}
if (reader != null) {
while (currentLine < from) {
reader.readLine();
currentLine++;
}
}
List<List<CellData>> datas = new ArrayList<List<CellData>>();
for (int i = 0; i < count; i++) {
String line = reader == null ? null : reader.readLine();
if (line == null)
break;
currentLine++;
String[] fs = line.split(",");
List<CellData> row = new ArrayList<CellData>();
for (int j = 0; j < fs.length; j++) {
CellData c = new CellData();
c.setStringValue(fs[j]);
row.add(c);
}
datas.add(row);
}
GridData d = new GridData();
List<String> headers = new ArrayList<String>();
for (JavaQueryOutputField f : outputFields)
headers.add(f.getName());
d.setStringHeaders(headers);
d.setData(datas);
return d;
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
} catch (FileNotFoundException e) {
throw new IllegalArgumentException(e);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 返回总行数,返回Integer.MAX_VALUE表示未知总行数
*/
public int getRowCount() {
return Integer.MAX_VALUE;
}
}
附件
源代码:MyJavaQueryProj.rar,扩展包:MyJavaQueryProj.ext,测试csv文件:test.csv