Xác định khả năng và luồng sự kiện

Phần này giới thiệu AdvancedExampleServlet2. AdvancedExampleServlet2 là ví dụ về cách triển khai nguồn dữ liệu xác định các tính năng và quy trình của sự kiện. Phần này cũng cung cấp hướng dẫn từng bước về cách chạy và kiểm thử AdvancedExampleServlet2.

Lưu ý: Bạn phải hoàn thành phần Bắt đầu trước khi bắt đầu phần này.

Giới thiệu AdvancedExampleServlet2

Lớp AdvancedExampleServlet2 nằm trong gói examples. Lớp này cung cấp phương thức triển khai mẫu để xác định các tính năng và quy trình của sự kiện.

Các phần quan trọng nhất của AdvancedExampleServlet2 được mô tả trong các phần sau:

Xác định luồng sự kiện

AdvancedExampleServlet2 xác định luồng sự kiện bằng cách ghi đè phương thức HttpServlet.doGet() và gọi nhiều hàm trợ giúp do DataSourceHelper cung cấp.

Đoạn mã sau sẽ ghi đè doGet(). Thông số HttpServletRequest đóng gói yêu cầu do hình ảnh trực quan cung cấp cho GVP. Tham số HttpServletResponse đóng gói phản hồi từ GVP cho hình ảnh truy vấn. Đoạn mã này cũng đặt dsRequest thành rỗng. dsRequest được sử dụng tại nhiều thời điểm trong suốt phần còn lại của mã.

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

Đoạn mã sau đây trích xuất các tham số yêu cầu từ HttpServletRequest để tạo ngữ cảnh mà yêu cầu chạy.

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

Đoạn mã sau đây sẽ lấy truy vấn từ đối tượng dsRequestphân tách thành hai truy vấn riêng biệt. Một truy vấn được gọi là truy vấn nguồn dữ liệu, truy vấn còn lại được gọi là truy vấn hoàn thành. Vì chức năng đã khai báo của nguồn dữ liệu là SELECT, nên truy vấn nguồn dữ liệu sẽ bao gồm một toán tử SELECT nếu đối tượng dsRequest chứa một thao tác SELECT. Truy vấn hoàn thành bao gồm mọi thao tác khác mà yêu cầu đòi hỏi, cũng có thể bao gồm một thao tác SELECT. Ví dụ: nếu truy vấn được yêu cầu là SELECT a ORDER BY b, thì truy vấn nguồn dữ liệu sẽ là SELECT a, b và truy vấn hoàn thành sẽ giống với truy vấn ban đầu SELECT a ORDER BY b.

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

Đoạn mã sau lấy truy vấn nguồn dữ liệu do đoạn mã trước và HttpServletRequest, tạo, đồng thời tạo bảng dữ liệu. Hãy xem mục Sử dụng các tính năng để biết thêm thông tin.

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

Mã sau lấy truy vấn hoàn thành được tạo ra khi truy vấn được chia nhỏ, bảng dữ liệu được tạo bởi đoạn mã trước đó và ngôn ngữ người dùng từ hình ảnh truy vấn. Sau đó, mã này sẽ tạo một bảng dữ liệu mới.

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

Mã sau đây lấy bảng dữ liệu do đoạn mã trước tạo ra và các thông số yêu cầu từ HttpServletRequest. Mã này sẽ đặt phản hồi GVP. Vùng chứa GVP sẽ trả về phản hồi này cho hình ảnh truy vấn.

      DataSourceHelper.setServletResponse(newData, dsRequest, resp);

Xử lý lỗi

Đoạn mã sau sẽ tạo ra một ngoại lệ, nhận được thông báo thích hợp, định dạng phản hồi và đặt phản hồi GVP. Nếu dsRequest là rỗng, thì DataSourceRequest không có sẵn, có thể là do hàm khởi tạo không thành công. Trong trường hợp này, HttpRequest được sử dụng thay cho 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);
      }
    }

Sử dụng tham số URL

Đoạn mã sau lấy truy vấn nguồn dữ liệu đã được tạo khi truy vấn được phân tách và HttpServletRequest. HttpServletRequest có thể tuỳ ý bao gồm một tham số tableId được chỉ định làm một URL. Thông số tableId này xác định bảng dữ liệu được trả về như sau:

  • Nếu tham số tableId bị bỏ qua hoặc không phải là planets, thì nguồn dữ liệu sẽ trả về bảng dữ liệu về động vật.
  • Nếu tham số tableId được chỉ định là planets, thì nguồn dữ liệu sẽ trả về bảng dữ liệu các hành tinh.

Khi viết mã của riêng mình để trả về một bảng dữ liệu, bạn quyết định việc sử dụng thông số nào.

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

Sử dụng các tính năng thực hiện tác vụ

Đoạn mã sau đây sẽ truy vấn và tạo bảng dữ liệu 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;
}

Đoạn mã sau đây sẽ truy vấn và tạo bảng dữ liệu 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;
}

Chạy và thử nghiệm AdvancedExampleServlet2

Phần này cung cấp hướng dẫn về cách chạy và kiểm thử AdvancedExampleServlet2.

Để chạy và kiểm thử AdvancedExampleServlet2, hãy cập nhật ứng dụng web và thiết lập hình ảnh để truy vấn nguồn dữ liệu, như mô tả trong các phần sau:

Cập nhật ứng dụng web trên Apache Tomcat

Hãy làm theo hoặc điều chỉnh hướng dẫn dưới đây để cập nhật ứng dụng web của bạn trên Apache Tomcat. Hướng dẫn dành riêng cho Apache Tomcat trên hệ thống Windows:

  1. Tệp web.xml mà bạn từng sao chép vào thư mục WEB-INF đã chứa định nghĩa và mục ánh xạ cần thiết cho ví dụ này. Các dòng xác định điều này là:

    <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. Khởi động Tomcat hoặc khởi động lại Tomcat nếu Tomcat đang chạy.
  3. Nhấp vào đường liên kết sau:http://localhost:8080/myWebApp/advanced
    Màn hình sẽ hiển thị 6 đến 7 dòng văn bản, tuỳ thuộc vào chiều rộng màn hình. Văn bản bắt đầu bằng google.visualization.Query.setResponse và kết thúc bằng {v:'http://en.wikipedia.org/wiki/Tiger'}]}]}});
    Đây là phản hồi mà nguồn dữ liệu CSV mẫu gửi đến một hình ảnh trực quan.

Sử dụng hình ảnh để xem dữ liệu

Bạn có thể dùng tệp all_examples.html trong thư mục <data_source_library_install>/examples/src/html để xem hình ảnh dữ liệu.

Đoạn mã sau từ all_examples chỉ định GVP advanced, bảng planets, một truy vấn có chọn lọc và một hình ảnh biểu đồ thanh.

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

Để tham khảo phần giải thích về các hình ảnh trực quan khác có trong all_examples.html, hãy xem mục Sử dụng Lưu trữ dữ liệu bên ngoài.

Để biết thêm thông tin về cách chỉ định hình ảnh và sử dụng ngôn ngữ truy vấn, hãy xem nội dung Sử dụng biểu đồTài liệu tham khảo về ngôn ngữ truy vấn.

Hãy làm theo hoặc điều chỉnh các hướng dẫn dưới đây để xem hình ảnh trực quan về dữ liệu do nguồn dữ liệu nâng cao cung cấp:

  1. Nếu bạn chưa thực hiện, hãy sao chép tệp all_examples.html từ thư mục <data_source_library_install>/examples/src/html
    đến thư mục <tomcat_home>/webapps/myWebApp/.
     
  2. Nhấp vào đường liên kết sau: http://localhost:8080/myWebApp/all_examples.html trong trình duyệt. Bạn sẽ thấy các thông tin sau:

Bước tiếp theo

Để khám phá thêm các ví dụ được cung cấp với thư viện, hãy xem phần Ví dụ về tệp tham chiếu nhanh. Để tìm hiểu thêm về cách triển khai một nguồn dữ liệu phức tạp, hãy xem bài viết Mẹo triển khai.