+2

UTL_HTTP Package trong Oracle 11g

1. Giới thiệu sơ lược về Package.

a. Khái niệm

  • Package là một tập hợp các kiểu dữ liệu, biến lưu giữ giá trị và các thủ tục, hàm có mối liên hệ với nhau, được gộp chung lại.
  • Đặc điểm nổi bật nhất của package là khi một phần tử trong package được gọi thì toàn bộ nội dung của package sẽ được nạp vào trong hệ thống. Do đó, việc gọi tới các phần tử khác trong package sau này sẽ không phải mất thời gian nạp lại vào hệ thống, giúp nâng cao tốc độ thực hiện lệnh của toàn bộ hàm, thủ tục có trong package.

b. Cấu trúc của package

Một package có cấu trúc gồm 2 phần:

• Phần mô tả (specification): Định nghĩa các giao tiếp có thể có của package với bên ngoài. • Phần thân (body): Là phần cài đặt cho các giao tiếp có trong phần mô tả trên.

c. Sử dụng:

  • Sử dụng package khi các kiểu dữ liệu, biến lưu giữ giá trị và các thủ tục, hàm có mối liên hệ với nhau.
  • Package giúp:
    • Đơn giản trong việc thiết kế ứng dụng: tất cả các thông tin cần thiết đều được đặt trong phần đặc tả của package. Nội dung phần này có thể được soạn thảo và biên dịch độc lập với phần thân của package. Do đó, các hàm hay thủ tục gọi tới các thành phần của package có thể được biên dịch tốt.
    • Ẩn thông tin: Package cho phép sử dụng các thành phần bên trong dưới dạng public hay private. Tùy theo thiết kế, ta có thể truy cập hay ẩn dấu thông tin. Từ đó, có thể bảo vệ được tính năng toàn vẹn dữ liệu.
    • Nâng cao hiệu suất sử dụng: Ngay khi gọi một hàm hay thủ tục bất kỳ trong package lần đầu tiên, toàn bộ nội dung của package sẽ được nạp vào bộ nhớ. Do vậy, các hàm và thủ tục con trong package gọi đến sau có thể thực hiện ngay mà không cần nạp lại bộ nhớ. Làm giảm thao tác truy xuất vào, ra, nâng cao tốc độ.
    • ...

2. UTL_HTTP package.

a. Tổng quan

  • Với UTL_HTTP package, có thể viết các chương trình bằng PL/SQL dùng để giao tiếp với Webserver(dùng giao thức HTTP).
  • UTL_HTTP package có khả năng truy cập tài nguyên trên HTTPS cũng như HTTP.
  • Bao gồm các hàm REQUEST, REQUEST_PIECES để lấy địa chỉ trang web, kết nối tới trang và trả về dữ liệu lấy từ trang web.

b. Các hằng số:

  • HTTP Version: có kiểu dữ liệu là varchar2(10), được dùng trong hàm BEGIN_REQUEST. Gồm có: • HTTP_VERSION_1_0: • HTTP_VERSION_1:
  • Port: • Cổng mặc định của giao thức HTTP(DEFAULT_HTTP_PORT) là 80. • Cổng mặc định của giao thức HTTPS (DEFAULT_HTTPS_PORT) là 443.
  • Một số hằng số trạng thái: đều có kiểu dữ liệu là PLS_INTEGER(tham khảo trong link https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_http.htm#i1012366)

c. Các loại dữ liệu:

  • REQ Type: sử dụng kiểu Record trong PL/SQL để chứa một HTTP request. • Cú pháp:
TYPE req IS RECORD (
   url           VARCHAR2(32767),--địa chỉ trang web
   method        VARCHAR2(64),
   http_version  VARCHAR2(64));

• Các thông tin trả về cho req ở trạng thái chỉ đọc, sự thay đổi giá trị các thuộc tính trong bản ghi không ảnh hưởng đến yêu cầu.

  • Kiểu RESP: sử dụng kiểu Record trong PL/SQL để chứa một phản hồi HTTP. • Cú pháp:
TYPE resp IS RECORD (
   status_code    PLS_INTEGER,
   reason_phrase  VARCHAR2(256),
   http_version   VARCHAR2(64));

Trong đó:  Status_code: mã trạng thái được trả về bởi Web server, là số nguyên có 3 chữ số, đại diện cho kết quả của việc xử lý các yêu cầu từ web server.  Reason_phrase: các đoạn văn bản để mô tả cho status code được trả về bởi web server.  http_version: phiên bản của giao thức HTTP.

  • Kiểu Cookie và Cookie table: • Cookie có kiểu record trong PL/SQL(Cookie là các tệp mà trang web đã truy cập, lưu trữ thông tin duyệt Web).
TYPE cookie IS RECORD (
   name  VARCHAR2(256),
   value  VARCHAR2(1024),
   domain  VARCHAR2(256),
   expire  TIMESTAMP WITH TIME ZONE),
   path  VARCHAR2(1024),
   secure  BOOLEAN,
   version  PLS_INTEGER,
   comment  VARCHAR2(1024));

Trong đó:

  • Name: tên của HTTP cookie.
  • value :giá trị của cookie.
  • domain :miền mà cookie có hiệu lực.
  • expire : thời gian cookie hết hạn.
  • path :các tập hợp con của URL
  • Kiểu connection:dùng kiểu record để lưu kết nối cho các máy chủ và các cổng TCP/IP của một kết nối mạng, được giữ bền vững kể cả sau khi request hoàn tất. • Cú pháp:
TYPE connection IS RECORD (
   host  VARCHAR2(256),
   port  PLS_INTEGER,
   proxy_host  VARCHAR2(256),
   proxy_port  PLS_INTEGER,
   ssl  BOOLEAN);

d. Hoạt động:

  • Luồng hoạt động:

e. Một số hàm và thủ tục:

e1 ) Request và Request_pieces:

  • Từ chuỗi URL, kết nối với trang web và trả về dữ liệu lấy được từ trang Web đó(thường ở dạng HTML).
  • Hàm Request: • Cú pháp:
UTL_HTTP.REQUEST (
   url              IN VARCHAR2,
   proxy            IN VARCHAR2 DEFAULT NULL, 
   wallet_path      IN VARCHAR2 DEFAULT NULL
   wallet_password  IN VARCHAR2 DEFAULT NULL)
RETURN VARCHAR2;

Trong đó:

  • url: địa chỉ URL của trang Web.
  • wallet_path: đường dẫn đến Oracle Wallet chứa chứng chỉ truy cập vào địa chỉ URL.
  • wallet_password: mật khẩu truy cập wallet. • Trả về chuỗi có độ dài đến 2000 bytes, hàm này có thể sử dụng trực tiếp trong câu truy vấn SQL. Nếu trang Web được truy cập có dữ liệu hơn 2000 bytes thì hàm REQUEST trả về 2000 bytes đầu tiên. • Ví dụ: Lấy thông tin(dạng HTML) trang Web có địa chỉ: http://guides.rubyonrails.org/working_with_javascript_in_rails.html SELECT UTL_HTTP.REQUEST('http://guides.rubyonrails.org/working_with_javascript_in_rails.html') FROM DUAL; Kết quả:
  • Hàm Request_Pieces: • Cú pháp:
TYPE html_pieces IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;

UTL_HTTP.REQUEST_PIECES (
   url             IN VARCHAR2,
   max_pieces      IN NATURAL DEFAULT 32767,
   proxy           IN VARCHAR2 DEFAULT NULL,
   wallet_path     IN VARCHAR2 DEFAULT NULL,
   wallet_password IN VARCHAR2 DEFAULT NULL)
RETURN html_pieces;

• Kết quả: Nội dung của toàn bộ trang Web được trả về thành nhiều phần, mỗi phần lên đến 2000 bytes. Thường được lưu theo kiểu table của PL/SQL. • Ví dụ:

DECLARE 
x   UTL_HTTP.HTML_PIECES; 
 len PLS_INTEGER; 
 i INTEGER;
BEGIN 
 x := UTL_HTTP.REQUEST_PIECES('http://guides.rubyonrails.org/working_with_javascript_in_rails.html', 100); 
 DBMS_OUTPUT.PUT_LINE(x.count || ' pieces were retrieved.'); 
 IF x.count < 1 THEN 
    DBMS_OUTPUT.PUT_LINE('0'); 
ELSE 
 len := 0; 
 FOR i in 1..x.count LOOP 
    DBMS_OUTPUT.PUT_LINE(x(i));
 END LOOP; 
 DBMS_OUTPUT.PUT_LINE(i); 
END IF; 
END;

e2) Hàm GET_RESPONE:

  • Dùng để đọc HTTP response.
  • Cú pháp:
UTL_HTTP.GET_RESPONSE (
  r  IN OUT NOCOPY req) 
RETURN resp;

e3) Thủ tục READ_LINE:

  • Dùng để đọc và trả về nội dung 1 dòng của HTTP response.
  • Cú pháp:
UTL_HTTP.READ_LINE(
   r            IN OUT NOCOPY resp,
   data         OUT NOCOPY  VARCHAR2 CHARACTER SET ANY_CS,
   remove_crlf  IN  BOOLEAN DEFAULT FALSE);

Trong đó: • r: HTTP response • data: nội dung của thân HTTP response. • Remove_crlf: xóa kí tự xuống dòng nếu có giá trị TRUE.

e4) Thủ tục READ_TEXT

  • Dùng để đọc và trả về nội dung của HTTP response.
  • Cú pháp:
UTL_HTTP.READ_TEXT(
   r     IN OUT NOCOPY resp,
   data  OUT NOCOPY VARCHAR2 CHARACTER SET ANY_CS,
   len   IN PLS_INTEGER DEFAULT NULL);

e5) Thủ tục SET_AUTHENTICATION

  • Thủ tục này thiết lập thông tin xác thực trong tiêu đề của HTTP request. Web server cần thông tin này để cấp quyền.
  • Cú pháp:
UTL_HTTP.SET_AUTHENTICATION(
   r         IN OUT NOCOPY req, --request
   username  IN VARCHAR2,
   password  IN VARCHAR2,
   scheme    IN VARCHAR2 DEFAULT 'Basic',
   for_proxy IN BOOLEAN  DEFAULT FALSE);

e6) Thủ tục SET_RESPONSE_ERROR_CHECK

  • Nếu SET_RESPONSE_ERROR_CHECK được bật(có giá trị true), thì hàm GET_RESPONES sẽ thiết lập các ngoại lệ khi Web server trả về các mã trạng thái của các lỗi(từ 4xx- 5xx).
  • Cú pháp:
UTL_HTTP.SET_RESPONSE_ERROR_CHECK (
  enable  IN BOOLEAN DEFAULT FALSE);

e7) Thủ tục SET_WALLET

  • Khi UTL_HTTP giao tiếp với HTTP server thông qua SSL(Secured Socket Layer), HTTP server phải cung cấp một chứng chỉ bản quyền truy cập. Oracle Wallet là bắt buộc khi thực hiện một HTTPS request.
  • Để tạo một wallet, dùng Oracle Wallet Manager.
  • Cú pháp:
UTL_HTTP.SET_WALLET (
   path      IN VARCHAR2,--đường dẫn đến wallet
   password  IN VARCHAR2 DEFAULT NULL);--mật khẩu để thiết lập/mở wallet

f) Ví dụ:

a) Trường hợp với các trang web không yêu cầu chứng thực chứng chỉ:

DECLARE
req   utl_http.req;
resp  utl_http.resp;
value VARCHAR2(1024);
BEGIN
  req := utl_http.begin_request('http://stackoverflow.com/questions/1235679/ora-29270-too-many-open-http-requests');
  utl_http.set_header(req, 'User-Agent', 'Mozilla/4.0');
  resp := utl_http.get_response(req);
LOOP
utl_http.read_line(resp, value, TRUE);
dbms_output.put_line(value);
END LOOP;
utl_http.end_response(resp);
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
WHEN UTL_HTTP.TOO_MANY_REQUESTS THEN
  UTL_HTTP.END_RESPONSE(resp); 
END;

Kết quả:

4. Tài liệu tham khảo:


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí