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

Phần này giới thiệu về AdvancedExampleServlet2. AdvancedExampleServlet2 là một ví dụ về cách triển khai nguồn dữ liệu xác định các chức năng và luồng 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 tất 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 một ví dụ về cách triển khai xác định các chức năng và luồng 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(). Tham số HttpServletRequest đóng gói yêu cầu do hình ảnh trực quan thực hiện cho servlet. Tham số HttpServletResponse đóng gói phản hồi từ servlet đến hình ảnh truy vấn. Đoạn mã này cũng đặt dsRequest thành rỗng. dsRequest được sử dụng ở nhiều điểm trong 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 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 dsRequestchia truy vấn đó 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 là truy vấn hoàn thành. Vì khả năng đã khai báo của nguồn dữ liệu là SELECT, nên truy vấn nguồn dữ liệu bao gồm thao tác SELECT nếu đối tượng dsRequest có chứa thao tác SELECT. Truy vấn hoàn thành bao gồm tất cả thao tác khác theo yêu cầu, cũng có thể bao gồm 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 sẽ lấy truy vấn nguồn dữ liệu do đoạn mã trước đó và HttpServletRequest, tạo, rồi tạo một bảng dữ liệu. Hãy xem phần Sử dụng tính năng để biết thêm thông tin chi tiết.

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

Mã sau sẽ lấy truy vấn hoàn thành được tạo ra khi truy vấn được phân tách, bảng dữ liệu do đoạn mã trước tạo ra và ngôn ngữ của 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 sẽ lấy bảng dữ liệu do đoạn mã trước tạo ra và các tham số yêu cầu từ HttpServletRequest. Sau đó, mã này sẽ đặt phản hồi servlet. Vùng chứa servlet 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 phát hiện trường hợp ngoại lệ, nhận thông báo thích hợp, định dạng phản hồi và đặt phản hồi servlet. Nếu dsRequest có giá trị rỗng, DataSourceRequest sẽ không xuất hiện, có thể là do hàm khởi tạo bị lỗi. Trong trường hợp này, HttpRequest sẽ được 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 tách và HttpServletRequest. HttpServletRequest có thể tuỳ ý bao gồm tham số tableId được chỉ định dưới dạng URL. Tham số tableId này xác định bảng dữ liệu nào đượ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 độ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 sẽ quyết định cần lấy tham 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 chức năng

Đoạn mã sau đây sẽ lấy 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ẽ lấy 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 đưa ra 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 trực quan để 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

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

  1. Tệp web.xml mà trước đây bạn sao chép vào thư mục WEB-INF đã chứa định nghĩa và mục ánh xạ bắt buộc cho ví dụ này. Các dòng xác định việc 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 hiển thị từ 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 hình ảnh trực quan.

Sử dụng hình ảnh trực quan để 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 trực quan của dữ liệu.

Đoạn mã sau từ all_examples chỉ định servlet advanced, bảng planets, một truy vấn chọn và 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'));

Để biết nội dung giải thích về các hình ảnh trực quan khác có trong all_examples.html, hãy xem phần Sử dụng Cửa hàng dữ liệu bên ngoài.

Để biết thêm thông tin về cách chỉ định hình ảnh trực quan và sử dụng ngôn ngữ truy vấn, hãy xem phần 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 bên dưới để 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 thao tác này, hãy sao chép tệp all_examples.html từ thư mục <data_source_library_install>/examples/src/html
    vào 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 như sau:

Các bước tiếp theo

Để tìm hiểu thêm về các ví dụ được cung cấp cùng với thư viện, hãy xem phần Tài liệu tham khảo nhanh về ví dụ. Để 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 phần Mẹo triển khai.