3. Lớp URLConnection

URLConnection là một lớp trừu tượng biểu diễn một liên kết tích cực tới một tài nguyên được xác định bởi một URL.
Lớp URLConnection có hai mục đích khác nhau nhưng liên quan với nhau.

• Thứ nhất, nó cung cấp nhiều khả năng điều khiển hơn thông qua việc tương tác với một server chứ không phải lớp URL. Với URLConnection ta có thể kiểm tra các headerMIME được gửi bởi một Http Server phản ứng tương ứng. Ta cũng có thể sử dụng lớp URLConnection  để tải về các tệp nhị phân. Ngoài ra URLConnection cho phép bạn gửi dữ liệu trở lại Web server bằng lệnh POST. Chúng ta sẽ xem tất cả các kỹ thuật đó trong chương này.

• Thứ hai, URLConnection là một phần của cơ chế quản trị giao thức, cơ chế này còn bao gồm cả lớp URLStreamHandler. Ý tưởng đằng sau các trình quản trị giao thức rất đơn giản: chúng cho phép bạn phân tách các chi tiết xử lý một giao thức với việc xử lý các kiểu dữ liệu cụ thể, cung cấp các giao diện người dùng, và thực hiện các công việc khác mà một trình duyệt thường làm. Lớp cơ sở URLConnection là một lớp trừu tượng; để cài đặt một giao thức cụ thể bạn cần phải viết một lớp con. Các lớp con này có thể được tải bởi các ứng dụng của riêng bạn hay bởi các trình duyệt HotJava; trong tương lai, các ứng dụng Java có thể tải về các trình quản trị giao thức khi cần.
Mở các URLConnection
Một chương trình sử dụng lớp URLConnection trực tiếp theo một dãy các bước cơ bản sau:

• Xây dựng một đối tượng URL.
• Gọi phương thức openConnection() của đối tượng URL để tìm kiếm một đối tượng URLConnection cho URL đó.
• Cấu hình đối tượng URL.
•  Đọc các trường header.
• Nhận một luồng nhập và đọc dữ liệu.
• Nhận một luồng xuất và ghi dữ liệu.
•  Đóng liên kết.

Tuy nhiên, không phải lúc nào ta cũng phải thực hiện tất cả các bước này.
Ví dụ: Mở một URLConnection tới http:// http://www.microsoft.com

import java.net.*;
import java.io.*;

public class getURLConnection  {

public static void main(String[] args)  {

URL u;
URLConnection uc;
try {
u= new URL(“http://www.microsoft.com”);
try {
uc=u.openConnection();
} catch(IOException e) {
System.err.println(e);
}
}  catch(MalformedURLException e) {
System.err.println(e);
}
}
}

Mặc dù lớp URLConnection là một lớp trừu tượng nhưng nó có một phương thức được cài  đặt. Phương thức  đó là connect(); phương thức này tạo một liên kết tới một server; vì vậy nó phụ thuộc vào kiểu dịch vụ mà ta cài đặt (HTTP, FTP,..). Tất nhiên, ta có thể cảm thấy tiện lợi hay cần thiết phải nạp chồng các phương thức này trong lớp.

Rất nhiều các phương thức và các trường trong lớp URLConnection có là phương thức protected. Mặt khác ta chỉ có thể truy cập tới chúng thông qua các thể hiện của lớp URLConnection hoặc các lớp con của nó. Rất ít khi chúng ta khởi tạo và truy cập trực tiếp các đối tượng; thay vào đó, môi trường thời gian chạy sẽ tạo ra các đối tượng khi cần tùy thuộc vào giao thức sử dụng. Sau  đó lớp sẽ  được khởi tạo bằng cách sử dụng các phương thức forName() và newInstance() của lớp java.lang.Class.

•  public abstract void connect() throws IOException
Phương thức connect() là một phương thức trừu tượng mở một liên kết tới một server. Tên của server được lấy ra từ một URL được lưu trữ như là một trường trong URLConnection, và được thiết lập bởi constructor của lớp. Các lớp con của lớp URLConnection nạp chồng các phương thức này để quản lý một kiểu liên kết cụ thể. Ví dụ, một phương thức connect() của lớp FileURLConnection chuyển đổi URL thành một filename trong thư mục tương ứng, tạo ra thông tin MIME cho file, và mở một luồng FileInputStream tới file. Phương thức connect() của lớp HttpURLConnection tạo ra một đối tượng HttpClient để kết nối với server. Phương thức openConnection() của đối tượng URL gọi phương thức connect() tương ứng, và trả về liên kết  đã  được mở. Vì vậy ta hiếm khi cần phải gọi phương thức connect() một cách trực tiếp.
Đọc dữ liệu từ một server
Dưới đây là các bước tối thiểu cần để tìm kiếm dữ liệu từ một URL bằng cách sử dụng đối tượng URLConnection:

o Bước 1: Xây dựng một đối tượng URL.
o Bước 2: Gọi phương thức openConnection() của lớp URL để tìm kiếm một đối tượng URL Connection cho đối tượng URL đó.
o Bước 3: Gọi phương thức getInputStream().
o Bước 4: Đọc từ luồng nhập bằng cách sử dụng API.

•  public Object getContent() throws IOException
Phương thức về mặt ảo giác giống như phương thức getContent() của lớp URL. Thực tế, phương thức URL.getContent() chỉ việc gọi phương thức getContent() tải về đối tượng được chọn bởi URL của URLConnection này. Để phương thức getContent() hoạt động, môi trường cần nhận dạng và hiểu kiểu nội dung. Hiện nay chỉ có một số kiểu nội dung được hiểu là text/plain, image/gif, và image/jpeg. Bạn có thể cài đặt thêm các kiểu trình quản lý nội dung khác có thể hiểu các kiểu nội dung khác. Phương thức getContent() chỉ làm việc với các giao thức như HTTP mà có một sự hiểu biết rõ ràng về các kiểu nội dung MIME. Nếu kiểu nội dung không được biết trước, hoặc giao thức không hiểu các kiểu nội dung, thì ngoại lệ UnknownServicException được đưa ra.

•  public InputStream getInputStream()
Phương thức getContent() chỉ làm việc khi Java có một trình quản lý nội dung cho kiểu nội dung. Nếu không phải trường hợp này, bạn có lẽ sẽ cần một luồng InputStream chung, luồng này cho phép bạn tự đọc và phân tích dữ liệu. Để làm như vậy, cần gọi phương thức getInputStream(). Phương thức này cũng hữu ích khi trình quản lý nội dung có sẵn không thực hiện chính xác cái mà bạn muốn.

Ví dụ: Tải về một trang web thông qua một URL.

import java.net.*;
import java.io.*;

public class  viewsource {

public static void main(String[] args)   {

String thisLine;
URL u;
URLConnection uc;
if(args.length>0) {

try{
u =new URL(args[0]);
try{
uc=u.openConnection();
DataInputStream theHtml = new DataInputStream(uc.getInputStream());
try{
while((thisLine=theHtml.readLine())!=null) {
System.out.println(thisLine);
}
} catch(Exception e) {
System.err.println(e);
}
} catch(Exception e) {
System.err.println(e);
}
} catch(MalformedURLException e) {
System.err.println(args[0]+” is not a parseable URL”);
System.err.println(e);
}

}

}

}

Phương thức openStream() của lớp URL trả về  đối tượng InputStream từ  đối tượng URLConnection.

•  public OutputStream getOutputStream()
Đôi khi bạn cần phải ghi dữ liệu vào một URLConnection-chẳng hạn khi bạn muốn gửi dữ liệu tới một web server sử dụng lệnh POST. Phương thức getOutputStream() trả về một luồng OutputStream trên đó bạn có thể ghi dữ liệu để truyền tới một server. Vì một URLConnection không cho phép xuất kết quả ra ở chế độ mặc định, bạn phải gọi phương thức setDoOutput() trước khi yêu cầu một luồng xuất. Mỗi khi bạn có một luồng OutputStream thông thường bạn phải gắn nó với luồng DataOutputStream hoặc một lớp con khác của lớp OutputStream mà đưa ra nhiều đặc trưng hơn.
Ví dụ:

try{

URL u = new URL(“http:// http://www.somehost.com/cgi-bin/acgi”);
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(uc.getOutputStream());
dos.writeByte(“Herre is some data”);
} catch(Exception e) {
System.err.println(e);
}

Sự khác biệt giữa URL và URLConnection là:

•  URLConnection cho phép truy xuất tới header HTTP.
• URLConnection có thể cấu hình các tham số yêu cầu được gửi cho server.
• URLConnection có thể ghi dữ liệu lên server cũng như đọc dữ liệu từ server.

Các bài liên quan:

Lập trình mạng trong Java(Phần 2)
Lập trình mạng trong Java(Phần4)