Definiowanie możliwości i przebiegu zdarzeń

W tej sekcji przedstawiamy AdvancedExampleServlet2. AdvancedExampleServlet2 to przykładowa implementacja źródła danych, która określa możliwości i przepływ zdarzeń. W tej sekcji znajdziesz też szczegółowe instrukcje uruchamiania i testowania AdvancedExampleServlet2.

Uwaga: przed rozpoczęciem tej sekcji musisz wypełnić sekcję Pierwsze kroki.

Przedstawiamy AdvancedExampleServlet2

Klasa AdvancedExampleServlet2 znajduje się w pakiecie examples. Ta klasa zawiera przykładową implementację, która określa możliwości i przepływ zdarzeń.

Najważniejsze części atrybutu AdvancedExampleServlet2 zostały opisane w tych sekcjach:

Definiowanie przebiegu zdarzeń

Funkcja AdvancedExampleServlet2 definiuje przepływ zdarzeń, zastępując metodę HttpServlet.doGet() i wywołując różne funkcje pomocnicze udostępniane przez funkcję DataSourceHelper.

Ten fragment kodu zastępuje doGet(). Parametr HttpServletRequest zawiera żądanie wysłane do serwletu przez wizualizację. Parametr HttpServletResponse zawiera odpowiedź z serwletu na wizualizację wykonującą zapytanie. Ten fragment kodu ustawia też dla pola dsRequest wartość null. dsRequest jest używany w różnych miejscach w kodzie.

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    DataSourceRequest dsRequest = null;

Ten fragment kodu wyodrębnia parametry żądania z HttpServletRequest, aby utworzyć kontekst, w którym działa żądanie.

    try {
      // Extract the request parameters.
      dsRequest = new DataSourceRequest(req);

Ten fragment kodu pobiera zapytanie z obiektu dsRequest i dziele je na 2 osobne zapytania. Jedno jest nazywane zapytaniem źródła danych, a drugie – zapytaniem uzupełniającym. Zadeklarowana zdolność źródła danych to SELECT, dlatego zapytanie do źródła danych składa się z operacji SELECT, jeśli obiekt dsRequest zawiera operację SELECT. Zapytanie polegające na zakończeniu składa się ze wszystkich innych operacji wymaganych przez żądanie, które mogą też obejmować operację SELECT. Jeśli np. żądane zapytanie ma postać SELECT a ORDER BY b, zapytanie do źródła danych będzie miało postać SELECT a, b, a zapytanie o ukończenie będzie takie samo jak pierwotne zapytanie SELECT a ORDER BY b.

      // Split the query.
      QueryPair query = DataSourceHelper.splitQuery(dsRequest.getQuery(), Capabilities.SELECT);

Ten fragment kodu pobiera zapytanie dotyczące źródła danych utworzone przez poprzedni fragment kodu oraz HttpServletRequest, i tworzy tabelę danych. Więcej informacji znajdziesz w sekcji Korzystanie z możliwości.

      // Generate the data table.
      DataTable data = generateMyDataTable(query.getDataSourceQuery(), req);

Poniższy kod pobiera zapytanie ukończenia, które zostało utworzone podczas podziału zapytania, tabelę danych wygenerowaną przez poprzedni fragment kodu i język użytkownika z wizualizacji do wykonywania zapytań. Następnie kod tworzy nową tabelę danych.

      // Apply the completion query to the data table.
      DataTable newData = DataSourceHelper.applyQuery(query.getCompletionQuery(), data,
          dsRequest.getUserLocale());

Ten kod korzysta z tabeli danych wygenerowanej przez poprzedni fragment kodu, a parametrów żądania z HttpServletRequest. Kod ustawia odpowiedź serwletu. Kontener serwletu zwraca tę odpowiedź do wizualizacji zapytań.

      DataSourceHelper.setServletResponse(newData, dsRequest, resp);

Obsługa błędów

Poniższy fragment kodu wykrywa wyjątek, pobiera odpowiedni komunikat, formatuje odpowiedź i ustawia odpowiedź serwletu. Jeśli dsRequest ma wartość null, pole DataSourceRequest jest niedostępne, prawdopodobnie z powodu awarii konstruktora. W tym przypadku zamiast DataSourceRequest używany jest 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);
      }
    }

Używanie parametrów adresu URL

Ten fragment kodu wykorzystuje zapytanie dotyczące źródła danych, które zostało utworzone podczas dzielenia zapytania, oraz zapytanie HttpServletRequest. HttpServletRequest może opcjonalnie zawierać parametr tableId określony jako adres URL. Parametr tableId określa, która tabela danych jest zwracana w ten sposób:

  • Jeśli parametr tableId zostanie pominięty lub ma wartość inną niż planets, źródło danych zwróci tabelę danych o zwierzętach.
  • Jeśli parametr tableId jest określony jako planets, źródło danych zwraca tabelę danych planet.

Pisząc własny kod zwracający tabelę danych, wybierasz parametry, które należy zastosować.

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

Korzystanie z funkcji

Ten fragment kodu wykorzystuje zapytanie i wygeneruje tabelę danych 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;
}

Ten fragment kodu wykorzystuje zapytanie i wygeneruje tabelę danych 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;
}

Uruchamianie i testowanie AdvancedExampleServlet2

Z tej sekcji dowiesz się, jak uruchamiać i testować AdvancedExampleServlet2.

Aby uruchomić i przetestować AdvancedExampleServlet2, zaktualizuj aplikację internetową i skonfiguruj wizualizację, która wysyła zapytanie do źródła danych, zgodnie z opisem w tych sekcjach:

Aktualizowanie aplikacji internetowej na serwerze Apache Tomcat

Wykonaj lub dostosuj poniższe instrukcje, aby zaktualizować aplikację internetową na serwerze Apache Tomcat. Te instrukcje dotyczą serwera Apache Tomcat w systemie Windows:

  1. Plik web.xml skopiowany wcześniej do katalogu WEB-INF zawiera już definicję i mapowanie wymagane w tym przykładzie. Definiują to następujące wiersze:

    <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. Uruchom program Tomcat lub uruchom go ponownie, jeśli jest już uruchomiony.
  3. Kliknij ten link:http://localhost:8080/myWebApp/advanced
    Na ekranie wyświetla się 6–7 wierszy tekstu w zależności od szerokości ekranu. Tekst zaczyna się od google.visualization.Query.setResponse , a kończy na {v:'http://en.wikipedia.org/wiki/Tiger'}]}]}});
    To odpowiedź, którą przykładowy źródło danych CSV wysyła do wizualizacji.

Wyświetlanie danych za pomocą wizualizacji

Plik all_examples.html z katalogu <data_source_library_install>/examples/src/html może służyć do wyświetlania wizualizacji danych.

Ten fragment kodu z all_examples określa serwlet advanced, tabelę planets, zapytanie wyboru i wizualizację na wykresie słupkowym.

query = new google.visualization.Query('advanced?tableId=planets&tq=select planet,mass');
...
var chart = new google.visualization.BarChart(document.getElementById('advanced_div'));

Omówienie innych wizualizacji dostępnych w tabeli all_examples.html znajdziesz w sekcji Korzystanie z zewnętrznego magazynu danych.

Więcej informacji o tym, jak określić wizualizację i używać języka zapytań, znajdziesz w artykułach Korzystanie z wykresów i dokumentacja języka zapytań.

Wykonaj lub dostosuj te instrukcje, aby wyświetlić wizualizację danych dostarczanych przez zaawansowane źródło danych:

  1. Skopiuj plik all_examples.html z katalogu <data_source_library_install>/examples/src/html
    do katalogu <tomcat_home>/webapps/myWebApp/ (jeśli jeszcze tego nie zrobiono).
     
  2. W przeglądarce kliknij ten link: http://localhost:8080/myWebApp/all_examples.html. Powinny wyświetlić się te informacje:

Dalsze kroki

Więcej informacji o przykładach dostępnych w bibliotece znajdziesz w krótkim przewodniku o przykładach. Więcej o implementowaniu złożonego źródła danych dowiesz się z artykułu Wskazówki dotyczące implementacji.