1、简介
在Smartbi中的接口主要可以简单分为如下几种:
服务端SDK
RMI接口
HTTP请求
它们的接口调用方式不同,风格差异较大,基本上能够满足各种场景下的集成需求。
2、Smartbi服务器端SDK
如果第三方系统是Java系统,则可以搭建好集成的环境后,直接调用Smartbi的提供的SDK。调用步骤如下:
1、调用示例
// 1、指定Smartbi服务器地址 ClientConnector connector = new ClientConnector(SMARTBI_URL); // 2、完成登录 boolean isLogin = connector.open(USER_NAME, PASS_WORD); if(!isLogin) { System.out.println("服务器登录访问失败"); return; } // 3、创建调用的接口对象 UserManagerService userManagerService = new UserManagerService(connector); List<? extends IDepartment> department = userManagerService.getDepartmentsOfCurrentUser(); for (IDepartment item : department) { System.out.println(item.getAlias()); }
2、接口获取
V11版本API文档:https://wiki.smartbi.com.cn/pages/viewpage.action?smt_poid=43&pageId=111889746
其他版本:打开wiki文档->选择对应版本的帮助文档->搜索关键字API→确认为对应版本文档后访问
3、RMIServlet接口
1、概述
在Smartbi上除去上面文档中记录的SDK接口之外,还有许多隐藏的方法可以使用,即RMIServlet接口。SDK接口是经过封装之后的稳定的接口,而RMIServlet接口是未明确暴露出来的接口,在版本变更时可能会有所改动或过时,所以这类接口仅支持如下两种场景:
适用于Java API文档尚未支持,但是当前需要立即使用的情况;
适用于调用自行开发的扩展包中的RMIServlet接口;
另外特别提醒,若在集成系统中使用该类接口,在大版本升级时请充分测试后再上线生产。
2、接口获取
RMIServlet接口的获取可以使用请求抓包的方式来获取,大部分请求在浏览器控制台的network中就能监控到,在抓取网络请求时,需要在访问地址上添加debug=true
的参数进入调试模式,否则抓取到的请求是加密之后的字符,无法确定请求的参数信息。添加了参数访问了之后打开浏览器控制台复现操作之后可以从浏览器控制台中监控请求返回体确认是需要的数据后,查看其请求负载即可找到对应的接口。
3、调用示例
在Java集成环境中可以通过使用ClientConnector
提供的remoteInvoke
方法来调用。另外注意remoteInvoke
方法不仅可以调用RMIServlet的请求,还可以调用SDK请求里的类和方法。remoteInvoke
方法最终会返回一个InvokeResult
类型的对象,调用该对象的getResult
方法可以得到一个Object
类型的对象,而这个对象实际上是一个JSON对象。
// 1、2步登录部分不变
// ...
// 3、调用RMI接口
// connector.remoteInvoke(调用类, 类中的指定方法, [方法的参数数组]);
InvokeResult result = connector.remoteInvoke("CatalogService", "getCatalogElementById",new Object[] {"I8a8a9aa90195419041906f790195419ba0140001"});
// 4、获取结果
JSONObject object = (JSONObject) result.getResult();
System.out.println(object.get("fullPath"));
4、HTTP请求接口
1、简介
随着编程语言的日渐丰富,第三方系统也并不一定是用java进行开发,此时就会面临不同语言是否支持调用java接口的问题,即便部分编程语言支持,但是使用起来仍会有诸多不便。面临这一类问题时,一般情况下是使用同样的http请求在桥接各个系统,当前Smartbi也支持部分http请求的接口。
当前系统支持的HTTP请求接口大致可分为如下几种:
RMIServlet接口
RMIServlet接口也可以通过HTTP的POST请求来提交获取接口的返回值
数据模型接口
包括数据模型的创建、更新、取数等
新资源模块接口
V11的即系查询、透视分析导出接口
Smartbi API 接口插件
该扩展包将一些常用的后端API接口,封装成可 HTTP 方式调用的接口,避免大量jar包的引入。
参考文档:https://wiki.smartbi.com.cn/pages/viewpage.action?smt_poid=43&pageId=136914754
2、HTTP请求使用RMIServlet接口示例
为了方便发送http请求,这里我们使用hutool
工具包里封装好的HttpRequest
类来发送http请求,简单的调用RMIServlet的示例如下:
注意:
请求接口调用时,需要先登录成功后再基于该会话调用其他接口,可使用UserService的login方法
不同接口的http请求设置
header
的Content-Type
不一样,请注意根据接口文档的内容选择合适的Content-Type
代码未做会话保持,为避免登录会话过多,实现会话复用可基于会话定时发起noop请求(smartbi/vsion/noop.jsp)会话保持
示例代码未包含其他servlet调用,如报表导出、资源迁移、文件上传等
public class SmartbiHttpAPITest {
private final static String SMARTBI_URL = "http://localhost:18080/smartbi";
public final static String SERVLET_URL = SMARTBI_URL+"/vision/RMIServlet";
private final static String USER_NAME = "admin";
private final static String PASS_WORD = "admin";
public static void main(String[] args) {
// 1、获取Smartbi的登录信息
Map<String, Object> loginParam = createRMIParam("UserService", "login",new Object[] {USER_NAME,PASS_WORD} );
HttpResponse loginResponse = sendPostRequest(SERVLET_URL,loginParam,null);
if (!isLogin(loginResponse.body())) {
System.out.println("登录失败");
return;
}
// 2、拿到登录cookie
List<HttpCookie> cookies = loginResponse.getCookies();
// 3、http的方式调用RMIServlet接口
Map<String, Object> catalogParam = createRMIParam("CatalogService",
"getCatalogElementById",
new Object[] {"I8a8a9aa90195419041906f790195419ba0140001"});
HttpResponse catalogResponse = sendPostRequest(SERVLET_URL,catalogParam,cookies);
// 4、获取请求返回结果
System.out.println(catalogResponse.body());
}
public static Map<String, Object> createRMIParam(String className,String methodName,Object[] params) {
Map<String, Object> rmiParam = new HashMap<String, Object>();
rmiParam.put("className", className);
rmiParam.put("methodName", methodName);
rmiParam.put("params", new JSONArray(params).toString());
return rmiParam;
}
public static HttpResponse sendPostRequest(String url, Map<String, Object> requestBody, List<HttpCookie> list) {
// 发送POST请求
try (HttpResponse response = HttpRequest.post(url)
// RMIServlet是使用form表单的方式提交
.header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
.form(requestBody)
.cookie(list)
.execute()) {
// 返回响应结果
return response;
} catch (Exception e) {
throw new RuntimeException("请求异常",e);
}
}
public static boolean isLogin(String result) {
JSONObject resultJson = new JSONObject(result);
if (resultJson.get("result") == null) {
return false;
}
return resultJson.get("result",Boolean.class);
}
}
5、扩展
在调用Smartbi请求时可以发现,必不可少的步骤是获取Smartbi的登录会话,登录用户是调用接口时鉴权的重要依据,所以调用时一定需要先完成登录。但是实际集成场景时往往可能会因为单点登录、请求限制等导致调用异常,此时就需要根据当前的单点登录场景灵活修改调用的方式。