定义功能和事件流

本部分将介绍 AdvancedExampleServlet2AdvancedExampleServlet2 是一个示例数据源实现,用于定义功能和事件流。本部分还提供了有关如何运行和测试 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 的请求参数。 然后,代码会设置 servlet 响应。该 servlet 容器会将此响应返回给查询可视化图表。

      DataSourceHelper.setServletResponse(newData, dsRequest, resp);

处理错误

以下代码段捕获异常,获取适当的消息,设置响应的格式,并设置 servlet 响应。如果 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);
      }
    }

使用网址参数

以下代码段接受在查询被拆分后创建的数据源查询和 HttpServletRequestHttpServletRequest 可以选择性地包含指定为网址的 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:

  1. 您之前复制到 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> 
  2. 启动 Tomcat,或重新启动 Tomcat(如果 Tomcat 已在运行)。
  3. 点击以下链接: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 中包含的其他可视化图表,请参阅使用外部数据存储区部分。

如需详细了解如何指定可视化元素以及如何使用查询语言,请参阅使用图表查询语言参考

请按照下面的说明或修改高级数据源提供的数据的可视化图表:

  1. 如果尚未将 all_examples.html 文件从 <data_source_library_install>/examples/src/html 目录
    复制到 <tomcat_home>/webapps/myWebApp/ 目录,请执行此操作。
     
  2. 在浏览器中点击以下链接:http://localhost:8080/myWebApp/all_examples.html。您应该会看到以下内容:

后续步骤

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