本部分介绍了 AdvancedExampleServlet2。AdvancedExampleServlet2 是数据源实现示例,用于定义功能和事件流。本部分还提供了有关如何运行和测试 AdvancedExampleServlet2 的分步说明。
注意:您必须先完成使用入门部分,然后才能开始本部分。
隆重推出AdvancedExampleServlet2
AdvancedExampleServlet2 类位于 examples 软件包中。此类提供了一个示例实现,用于定义功能和事件流。
以下各部分介绍了 AdvancedExampleServlet2 最重要的部分:
定义事件流
AdvancedExampleServlet2 通过替换 HttpServlet.doGet() 方法并调用 DataSourceHelper 提供的各种辅助函数来定义事件流。
以下代码段会替换 doGet()。HttpServletRequest 参数可封装可视化图表向 servlet 发出的请求。HttpServletResponse 参数封装了从 servlet 到查询可视化图表的响应。此代码段还会将 dsRequest 设置为 null。dsRequest 在其余代码的不同点使用。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
DataSourceRequest dsRequest = null;
以下代码段从 HttpServletRequest 中提取请求参数,以创建发送请求的上下文。
try {
// Extract the request parameters.
dsRequest = new DataSourceRequest(req);
以下代码段从 dsRequest 对象中获取查询, 并将其拆分为两个单独的查询。其中一个查询称为数据源查询,另一个称为完成查询。由于数据源声明的功能是 SELECT,因此如果 dsRequest 对象包含 SELECT 操作,则数据源查询将包含 SELECT 操作。完成查询包含请求所需的所有其他操作,其中可能还包括 SELECT 操作。例如,如果请求的查询是 SELECT a ORDER
BY b,则数据源查询将为 SELECT a, b,并且完成查询将与原始查询 SELECT a ORDER BY b 相同。
// Split the query.
QueryPair query = DataSourceHelper.splitQuery(dsRequest.getQuery(), Capabilities.SELECT);
以下代码段 将接受上一个代码段创建的数据源查询和 HttpServletRequest,,并创建一个数据表。如需了解详情,请参阅使用功能部分。
// Generate the data table.
DataTable data = generateMyDataTable(query.getDataSourceQuery(), req);
以下代码 接受拆分查询时生成的完成查询、上一个代码段生成的数据表,以及查询可视化图表中的用户语言区域。然后,该代码会创建一个新的数据表。
// Apply the completion query to the data table.
DataTable newData = DataSourceHelper.applyQuery(query.getCompletionQuery(), data,
dsRequest.getUserLocale());
以下代码会获取 上一个代码段生成的数据表,以及来自 HttpServletRequest 的请求参数。。然后,该代码会设置 WebView 响应。此 WebView 容器会将此响应返回到可视化图表中。
DataSourceHelper.setServletResponse(newData, dsRequest, resp);
处理错误
以下代码段 会捕获异常,获取相应的消息,设置响应的格式,并设置 WebView 响应。如果 dsRequest 为 null,则 DataSourceRequest 不可用,这可能是因为构造函数失败。在这种情况下,系统会使用 HttpRequest(而非 DataSourceRequest)。
catch (RuntimeException rte) {
log.error("A runtime exception has occured", rte);
ResponseStatus status = new ResponseStatus(StatusType.ERROR, ReasonType.INTERNAL_ERROR,
rte.getMessage());
if (dsRequest == null) {
dsRequest = DataSourceRequest.getDefaultDataSourceRequest(req);
}
DataSourceHelper.setServletErrorResponse(status, dsRequest, resp);
} catch (DataSourceException e) {
if (dsRequest != null) {
DataSourceHelper.setServletErrorResponse(e, dsRequest, resp);
} else {
DataSourceHelper.setServletErrorResponse(e, req, resp);
}
}
使用网址参数
以下代码段 接受拆分查询时创建的数据源查询以及 HttpServletRequest。HttpServletRequest 可以选择性地包含指定为网址的 tableId 参数。此 tableId 参数决定了返回哪个数据表,如下所示:
- 如果省略
tableId参数或使用planets以外的任何参数,数据源会返回动物数据表。 - 如果将
tableId参数指定为planets,则数据源会返回行星数据表。
当您编写自己的代码以返回数据表时,需要决定要采用哪些参数。
private DataTable generateMyDataTable(Query query, HttpServletRequest req)
throws TypeMismatchException {
String tableID = req.getParameter("tableId");
if ((tableID != null) && (tableID.equalsIgnoreCase("planets"))) {
return generatePlanetsTable(query);
}
return generateAnimalsTable(query);
}
使用功能
以下代码段会接受该查询并生成 animals 数据表。
private DataTable generateAnimalsTable(Query query) throws TypeMismatchException {
DataTable data = new DataTable();
List requiredColumns = getRequiredColumns(query,
ANIMAL_TABLE_COLUMNS);
data.addColumns(requiredColumns);
// Populate the data table
for (String key : animalLinksByName.keySet()) {
TableRow row = new TableRow();
for (ColumnDescription selectionColumn : requiredColumns) {
String columnName = selectionColumn.getId();
if (columnName.equals(ANIMAL_COLUMN)) {
row.addCell(key);
} else if (columnName.equals(ARTICLE_COLUMN)) {
row.addCell(animalLinksByName.get(key));
}
}
data.addRow(row);
}
return data;
}
以下代码段会接受该查询并生成 planets 数据表。
private DataTable generatePlanetsTable(Query query) throws TypeMismatchException {
DataTable data = new DataTable();
List requiredColumns = getRequiredColumns(
query, planetTableColumns);
data.addColumns(requiredColumns);
// Populate data table
for (Planet planet : Planet.values()) {
TableRow row = new TableRow();
for (ColumnDescription selectionColumn : requiredColumns) {
String columnName = selectionColumn.getId();
if (columnName.equals(PLANET_COLUMN)) {
row.addCell(planet.name());
} else if (columnName.equals(MASS_COLUMN)) {
row.addCell(planet.getMass());
} else if (columnName.equals(GRAVITY_COLUMN)) {
row.addCell(planet.getSurfaceGravity());
} else if (columnName.equals(MOONS_COLUMN)) {
row.addCell(planet.getNumberOfMoons());
}
}
data.addRow(row);
}
return data;
}
运行和测试 AdvancedExampleServlet2
本部分介绍如何运行和测试 AdvancedExampleServlet2。
如需运行和测试 AdvancedExampleServlet2,请更新您的 Web 应用,并设置查询数据源的可视化图表,如以下部分所述:
在 Apache Tomcat 上更新 Web 应用
请按照或调整下面的说明,在 Apache Tomcat 上更新您的 Web 应用。以下说明特定于 Windows 系统上的 Apache Tomcat:
- 您之前复制到
WEB-INF目录的web.xml文件已包含此示例所需的定义和映射。定义这些内容的行包括:
<servlet> <servlet-name>AdvancedExampleServlet2</servlet-name> <description> AdvancedExampleServlet2 </description> <servlet-class>AdvancedExampleServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>AdvancedExampleServlet2</servlet-name> <url-pattern>/advanced</url-pattern> </servlet-mapping>
- 启动 Tomcat;如果 Tomcat 已在运行,请重启。
- 点击以下链接:http://localhost:8080/myWebApp/advanced
屏幕会显示 6-7 行文字,具体取决于您的屏幕宽度。 文本以google.visualization.Query.setResponse开头并以{v:'http://en.wikipedia.org/wiki/Tiger'}]}]}});结尾
这是示例 CSV 数据源发送到可视化图表的响应。
使用可视化图表查看数据
<data_source_library_install>/examples/src/html 目录中的 all_examples.html 文件可用于查看数据的可视化图表。
all_examples 中的以下代码段指定了 advanced servlet、planets 表、select 查询和条形图可视化。
query = new google.visualization.Query('advanced?tableId=planets&tq=select planet,mass');
...
var chart = new google.visualization.BarChart(document.getElementById('advanced_div'));
如需了解 all_examples.html 中包含的其他可视化图表,请参阅使用外部数据存储区部分。
如需详细了解如何指定可视化图表和使用查询语言,请参阅使用图表和查询语言参考。
请按照或调整下面的说明,查看高级数据源提供的数据的可视化效果:
- 如果您尚未将
all_examples.html文件从<data_source_library_install>/examples/src/html目录
复制到<tomcat_home>/webapps/myWebApp/目录,请执行此操作。
- 在浏览器中点击以下链接:http://localhost:8080/myWebApp/all_examples.html。您应该会看到以下内容:

后续步骤
如需进一步探索该库提供的示例,请参阅快速参考示例。如需详细了解如何实现复杂的数据源,请参阅实现提示。