Определение возможностей и потока событий

В этом разделе представлен AdvancedExampleServlet2 . AdvancedExampleServlet2 — это пример реализации источника данных, который определяет возможности и поток событий. В этом разделе также приведены пошаговые инструкции по запуску и тестированию AdvancedExampleServlet2 .

Примечание . Вы должны заполнить раздел « Начало работы », прежде чем приступить к этому разделу.

Представляем AdvancedExampleServlet2

Класс AdvancedExampleServlet2 находится в пакете examples . Этот класс предоставляет пример реализации, определяющий возможности и поток событий.

Наиболее важные части AdvancedExampleServlet2 описаны в следующих разделах:

Определение потока событий

AdvancedExampleServlet2 определяет поток событий, переопределяя метод HttpServlet.doGet() и вызывая различные вспомогательные функции, предоставляемые DataSourceHelper .

Следующий фрагмент переопределяет doGet() . Параметр HttpServletRequest инкапсулирует запрос, сделанный визуализацией к сервлету. Параметр HttpServletResponse инкапсулирует ответ сервлета на визуализацию запроса. Этот фрагмент также устанавливает для 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 , запрос источника данных состоит из операции SELECT , если объект dsRequest включает операцию 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 . Затем код устанавливает ответ сервлета. Контейнер сервлета возвращает этот ответ запрашивающей визуализации.

      DataSourceHelper.setServletResponse(newData, dsRequest, resp);

Обработка ошибок

Следующий фрагмент перехватывает исключение, получает соответствующее сообщение, форматирует ответ и устанавливает ответ сервлета. Если dsRequest имеет значение null, DataSourceRequest недоступен, возможно, из-за сбоя конструктора. В этом случае вместо DataSourceRequest используется HttpRequest .

    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);
      }
    }

Использование параметров URL

Следующий фрагмент берет запрос к источнику данных, созданный при разделении запроса, и HttpServletRequest . HttpServletRequest может дополнительно включать параметр tableId , указанный в виде URL-адреса. Этот параметр tableId определяет, какая таблица данных возвращается, следующим образом:

  • Если параметр tableId опущен или имеет значение, отличное от planets , источник данных возвращает таблицу данных о животных.
  • Если параметр tableId указан как planets , источник данных возвращает таблицу данных 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 , обновите веб-приложение и настройте визуализацию, которая запрашивает источник данных, как описано в следующих разделах:

Обновление веб-приложения на Apache Tomcat

Следуйте приведенным ниже инструкциям или адаптируйте их, чтобы обновить веб-приложение на Apache Tomcat. Эти инструкции относятся к Apache Tomcat в системе Windows:

  1. Файл web.xml , который вы ранее скопировали в каталог WEB-INF уже содержит определение и сопоставление, необходимые для этого примера. Строки, которые определяют это:

    <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, если он уже запущен.
  3. Щелкните следующую ссылку: http://localhost:8080/myWebApp/advanced.
    На экране отображается 6-7 строк текста, в зависимости от ширины экрана. Текст начинается с google.visualization.Query.setResponse и заканчивается {v:'http://en.wikipedia.org/wiki/Tiger'}]}]}});
    Это ответ, который пример источника данных CSV отправляет в визуализацию.

Использование визуализации для просмотра данных

Файл all_examples.html в <data_source_library_install>/examples/src/html можно использовать для просмотра визуализации данных.

Следующий фрагмент из all_examples определяет advanced сервлет, таблицу planets , запрос выбора и визуализацию гистограммы.

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 в браузере. Вы должны увидеть следующее:

Следующие шаги

Для дальнейшего изучения примеров, поставляемых с библиотекой, см. Краткий справочник по примерам . Дополнительные сведения о реализации сложного источника данных см. в разделе Советы по внедрению .