Definiowanie możliwości i przebiegu wydarzeń

W tej sekcji opisujemy AdvancedExampleServlet2. AdvancedExampleServlet2 to przykładowa implementacja źródła danych, która definiuje możliwości i przepływ zdarzeń. W tej sekcji znajdziesz także szczegółowe instrukcje uruchamiania i testowania środowiska 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ładowe wdrożenie, które określa możliwości i przepływ zdarzeń.

Najważniejsze części właściwości AdvancedExampleServlet2 są opisane w tych sekcjach:

Definiowanie przepływu zdarzeń

AdvancedExampleServlet2 określa przepływ zdarzeń, zastępując metodę HttpServlet.doGet() i wywołując różne funkcje pomocnicze obsługiwane przez DataSourceHelper.

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

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

Ten fragment wyodrębnia parametry żądania z HttpServletRequest, aby utworzyć kontekst, w którym żądanie jest wykonywane.

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

Poniższy fragment pobiera zapytanie z obiektu dsRequest i łączy je w 2 oddzielne zapytania. Jedno zapytanie jest nazywane zapytaniem o źródło danych, a drugie – zapytanie o ukończenie. Zadeklarowane możliwości źródła danych to SELECT, dlatego zapytanie źródła danych składa się z operacji SELECT, jeśli obiekt dsRequest zawiera operację SELECT. Zapytanie ukończenia obejmuje wszystkie inne operacje wymagane przez żądanie, które mogą też obejmować operację SELECT. Jeśli na przykład żądane zapytanie to SELECT a ORDER BY b, zapytanie do źródła danych będzie miało wartość SELECT a, b, a zapytanie ukończenia będzie takie samo jak pierwotne zapytanie SELECT a ORDER BY b.

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

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

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

Ten kod stosuje zapytanie ukończone w trakcie podziału zapytania, bazę danych utworzoną przez poprzedni fragment i język użytkownika z wizualizacji zapytania. Kod tworzy nową tabelę danych.

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

Poniższy kod wykorzystuje tabelę danych utworzoną w poprzednim fragmencie kodu oraz parametry żądania z HttpServletRequest. Następnie kod ustawia odpowiedź serwletu. Kontener serwletu zwraca tę odpowiedź na wizualizację zapytań.

      DataSourceHelper.setServletResponse(newData, dsRequest, resp);

Obsługa błędów

Ten fragment kodu wykrywa wyjątek, pobiera odpowiednią wiadomość, formatuje odpowiedź i ustawia odpowiedź serwletu. Jeśli dsRequest ma wartość NULL, właściwość DataSourceRequest jest niedostępna, prawdopodobnie z powodu konstruktora. W tym przypadku zamiast DataSourceRequest pojawia się 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);
      }
    }

Parametry adresu URL

Następujący fragment kodu używa zapytania o źródło danych, które zostało utworzone podczas podziału zapytania, oraz 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 pominiesz parametr tableId lub którykolwiek inny element 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.

Gdy piszesz własny kod, by zwrócić tabelę danych, wybierasz, które parametry 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

Poniższy fragment kodu wykonuje zapytanie i generuje 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;
}

Poniższy fragment kodu wykonuje zapytanie i generuje 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

W tej sekcji znajdziesz instrukcje dotyczące uruchamiania i testowania środowiska AdvancedExampleServlet2.

Aby uruchomić i przetestować AdvancedExampleServlet2, zaktualizuj aplikację internetową i skonfiguruj wizualizację przeznaczoną dla źródła danych, jak opisano w tych sekcjach:

Aktualizowanie aplikacji internetowej w Apache Tomcat

Aby zaktualizować aplikację internetową na serwerze Apache Tomcat, wykonaj lub dostosuj podane niżej instrukcje. Te instrukcje dotyczą 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. Wiersze, które to definiują:

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

Wizualizacja do wyświetlania danych

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

Fragment kodu all_examples określa serwlet advanced, tabelę planets, wybrane zapytanie oraz wizualizację wykresu słupkowego.

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

Wyjaśnienia dotyczące innych wizualizacji dostępnych w 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 zapytania, znajdziesz w artykułach Korzystanie z wykresów i Informacje o języku zapytań.

Aby wyświetlić wizualizację danych przesłanych przez zaawansowane źródło danych, lub dostosować się do nich, wykonaj poniższe instrukcje:

  1. Skopiuj plik all_examples.html z <data_source_library_install>/examples/src/htmlkatalogu
    do katalogu <tomcat_home>/webapps/myWebApp/, jeśli jeszcze go nie masz.
     
  2. W przeglądarce kliknij ten link: http://localhost:8080/myWebApp/all_examples.html. Strona powinna wyglądać tak:

Następne kroki

Więcej przykładów znajdziesz w bibliotece. Zobacz przykłady. Więcej informacji o implementowaniu złożonego źródła danych znajdziesz we wskazówkach dotyczących implementacji.