1. Trang chủ
  2. » Luận Văn - Báo Cáo

Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx

59 330 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 59
Dung lượng 0,97 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bảng 6.1 Mô hình Record Store Mỗi record có một trường Record ID có kiểu dữ liệu integer, đóng vai trò như khóa chính trong bảng dữ liệu và một trường “Data” là một mảng các bytes để ch

Trang 1

Java Mobile

Thay thế cho hệ thống file, thiết bị MIDP lưu trữ thông tin qua các record stores Chúng ta có thể xem các record store này như một bảng dữ liệu gồm nhiều dòng record Mỗi dòng record có một số ID và gồm một mảng các bytes Người ta thường xem record store như một cấu trúc file phẳng (flat-file)

Bảng 6.1 Mô hình Record Store

Mỗi record có một trường Record ID có kiểu dữ liệu integer, đóng vai trò như khóa chính trong bảng dữ liệu và một trường “Data” là một mảng các bytes để chứa

dữ liệu Một tập hợp các record này được gọi là một record store (tương ứng với một bảng dữ liệu) Một ứng dụng MIDlet có thể có bao nhiêu record store tùy ý (kể

cả không có), mỗi record store được phân biệt bởi tên định danh duy nhất Mở rộng

ra, các Record Stores của các ứng dụng MIDlet cùng chung một bộ (suite) thì cũng phải có tên phân biệt

Tên của record store có thể chứa đến 32 ký tự Unicode (16 bits) và tên này phân biệt hoa thường

Các ứng dụng MIDlet không những truy xuất được các record stores do nó tạo ra

mà còn truy xuất được các record stores do các ứng dụng khác trong cùng một bộ (MIDlet Suite) tạo ra Đây là một lý do khiến các nhà phát triển đặt ra khái niệm MIDlet Suite, tuy nhiên các MIDlet không cùng một suite không thể truy xuất Record Suite của nhau Đây là một hạn chế của Record Store khi so sánh với hệ thống file trên các thiết bị khác

Một record store quản lý hai thông số để quản lý việc truy cập dữ liệu, hai thông

số này tự động được cập nhật khi có record được thêm, xóa hay sửa:

Trang 2

Java Mobile

• Số Version : đây là một giá trị integer Tuy nhiên, có một điều không may là giá trị khởi điểm của version không được định nghĩa bởi API Nếu chúng ta cần biết giá trị ban đầu này, ngay sau khi tạo record mới ta có thể gọi hàm getVersion()

• Ngày tháng: là một số long, thể hiện số millisecond tính từ nửa đêm ngày 1/1/1970 Chúng ta có thể lấy ra thông số này bằng hàm getLastModified() Các yêu cầu xử lý record store được thiết bị đồng bộ hóa tự động: khi có hai hay nhiều yêu cầu xử lý thì yêu cầu đến trước được xử lý trước và các yêu cầu xử lý khác sẽ được đặt vào hàng đợi

Các hàm xử lý Record Store thông dụng:

Mở một record store, tùy chọn tạo mới nếu record store chưa tồn tại

static void deleteRecordStore(String

rcdStoreName)

Xóa record store

static String[] listRecordStore() Liệt kê các record stores trong MIDlet

Suite

int addRecord(byte[] data, int offset, int

numBytes)

Thêm một record

void setRecord(int recordID,byte[]

newData,int offset, int numBytes)

Thay đổi nội dung một record

void deleteRecord(int RecordID) Xóa một record khỏi record store

byte[] getRecord(int RecordID) Lấy mảng byte chứa nội dung record

Trang 3

Java Mobile

int getRecord(int RecordID, byte[]

buffer, int offset)

Lấy nội dung record từ vị trí offset đưa vào mảng byte

int getRecordSize(int RecordID) Lấy kích thước của record

int getNextRecordID() Lấy ID của record tiếp theo int getNumRecords() Lấy số lượng Record trong Record

Store

int getSizeAvailable() Lấy dung lượng còn lại (bytes) được

phép dùng bởi Record Store

Ghi chú: Record ID được tính bắt đầu từ 1 chứ không phải từ 0 như chỉ số mảng

Sau đây là một ví dụ về việc nhập xuất dữ liệu thông qua record store bằng kỹ thuật stream Ví dụ đã được tinh giản và chỉ trình bày những phân đoạn chính

//Import các thư viện cần thiết

import java.io.*;

import javax.microedition.midlet.*;

Trang 4

Java Mobile

import javax.microedition.rms.*;

public class ReadWriteStreams extends MIDlet {

private RecordStore rs = null; // Record Store

static final String REC_STORE = "db_1"; // Tên của Record Store

public ReadWriteStreams() {

openRecStore(); // Hàm tạo Record Store

writeTestData(); // Hàm ghi dữ liệu

readStream(); // Hàm đọc dữ liệu

closeRecStore(); // Đóng Record Store

deleteRecStore(); // Xóa Record Store

} …

public void startApp() {

// Không có giao diện, chương trình sẽ ghi, đọc dữ liệu và thoát

destroyApp(false);

notifyDestroyed();

} public void openRecStore() {

try {

// Tạo record store mới nếu chưa tồn tại

rs = RecordStore.openRecordStore(REC_STORE, true );

} catch (Exception e) {

//Xuất thông báo lỗi

} }

public void closeRecStore() {

rs.closeRecordStore();

Trang 5

Java Mobile

} catch (Exception e) {

//Xuất thông báo lỗi

} }

public void deleteRecStore(){

if (RecordStore.listRecordStores() != null){

try{

RecordStore.deleteRecordStore(REC_STORE);

} catch (Exception e){

//Xuất thông báo lỗi

} }

} /* -

* Tạo 3 mảng để mô phỏng việc ghi dữ liệu

* -*/

public void writeTestData() {

String[] strings = {"String 1", "String 2"};

boolean[] booleans = {false, true};

int[] integers = {1 , 2};

writeStream(strings, booleans, integers);

} /* -

* Viết vào record store dùng stream

* -*/

public void writeStream(String[] sData, boolean[] bData, int[] iData) {

try{

Trang 6

Java Mobile

/* Tạo stream để viết dữ liệu, ở đây ta tạo ra 2 streams, một stream có tác dụng như buffer, stream còn lại để ghi dữ liệu vào Record*/

//Buffer

ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();

DataOutputStream strmDataType = new DataOutputStream(strmBytes);

byte[] record;

//Ba mảng có kích thước bằng nhau

for (int i = 0; i < sData.length; i++) {

Trang 7

Java Mobile

catch (Exception e){

//Xuất các thông báo lỗi

} }

byte[] recData = new byte[50];

// Tạo một stream làm buffer lấy dữ liệu từ mảng recData

ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);

// Tạo stream để xuất dữ liệu theo đúng khuôn dạng đã ghi

DataInputStream strmDataType = new DataInputStream(strmBytes);

for (int i = 1; i <= rs.getNumRecords(); i++){

// Lấy dữ liệu đưa vào mảng

rs.getRecord(i, recData, 0);

// Đọc lại theo đúng thứ tự đã ghi

System.out.println("Record #" + i);

System.out.println("UTF:" + strmDataType.readUTF()); System.out.println("Boolean: " +

strmDataType.readBoolean());

System.out.println("Int: " + strmDataType.readInt()); System.out.println(" -");

// Xóa dữ liệu buffer để bắt đầu ghi các phần tử tiếp theo

strmBytes.reset();

Trang 8

Java Mobile

} strmBytes.close();

strmDataType.close();

} catch (Exception e){

//Xuất các thông báo lỗi

} }

… }

Ví dụ trên đã nêu một cách cơ bản nhất các bước cần thiết để ghi dữ liệu và truy xuất dữ liệu bằng record store Ví dụ đã được tinh giản và chỉ nêu các hàm thật cần thiết Việc mở, ghi record, đọc record, đóng và xóa record được thể hiện thành từng hàm riêng biệt để tiện theo dõi Trong ví dụ trên có một số điểm ta cần chú ý:

Chỉ số RecordID bắt đầu từ 1 chứ không phải từ 0 như chỉ số của các phần tử trong mảng Nếu ta cố gắng truy xuất phần tử số 0 sẽ phát sinh lỗi

Tương tự như các hàm truy xuất I/O khác của Java, các hàm liên quan đến Record Store cần phải được đưa vào trong khối try – catch vì các hàm này có thể phát sinh các exceptions

Trong ví dụ trên chúng ta dùng stream để ghi và xuất dữ liệu có khuôn dạng; do đó khi chúng ghi theo trình tự nào thì xuất cũng phải theo trình tự đó

Trang 9

Java Mobile

6.2 Duyệt danh sách Record với RecordEnumeration

Ngay trên ví dụ vừa rồi, chúng ta duyệt qua danh sách các records trong record store bằng dòng lặp Đây là các tiếp cận được những lập trình viên nghĩ đến ban đầu

vì chúng ta đã nhận định các record như các dòng trong một bảng của CSDL Tuy nhiên, MIDP cung cấp cho chúng ta một công cụ thuận tiện và chính xác hơn để

duyệt qua các record trong một record store Chúng ta đề cập đến khái niệm “chính

xác hơn” ở đây vì lý do khi duyệt bằng vòng lặp thực chất có thể gây nên một

exception trong chương trình Giả sử chúng ta có 3 record đánh số từ 1 đến 3, vì lý

do nào đó chúng ta xóa record số 2 bằng phương thức deleteRecord(int RecordID) thì số 2 không bao giờ được sử dụng để gán làm RecordID cho một record khác Vậy khi ta duyệt bằng vòng lặp, giả sử i từ 1 đến 3, khi giá trị i=2 sẽ gây ra một lỗi exception Khi đó, chúng ta bắt buộc phải duyệt bằng công cụ enumeration Ngoài

ra, khi chúng ta sử dụng các chức năng lọc (filter) và sắp xếp (sort) các record, giá trị trả về sẽ là một RecordEnumeration vì các RecordID lúc này không tuân theo bất

// lấy thông tin record tiếp theo ra buffer

String str = new String(re.nextRecord());

//xử lý tùy theo yêu cầu

}

Trang 10

Java Mobile

Hàm enumerateRecord nhận vào ba tham số:

• Tham số đầu là bộ lọc (filter), nếu không muốn lọc record ta để null

• Tham số thứ nhì là bộ sắp xếp (sort), nếu không muốn sắp xếp ta cũng để null Nếu cả hai tham số trên đều là null thì các record được lấy ra và sắp xếp theo thứ tự bất kỳ

• Tham số cuối cùng là một biến boolean bUpdate, nếu bUpdate là true thì khi danh sách các record có sự thay đổi (bị thêm, xóa hay sửa) biến RecordEnumeration sẽ tự cập nhật, nếu là false chúng ta phải tự cập nhật bằng hàm rebuild()

Sau đây là các hàm thông dụng nhất của lớp RecordEnumeration

Lớp javax.microedition.rms.RecordEnumeration

int numRecords() Số lượng records trong tập hợp byte[] nextRecord() Lấy record kế tiếp, duyệt theo thứ tự tiến

(forward) hay không?

bolean hasPrevioussElement() Kiểm tra còn record để tiếp tục duyệt lùi

(backward) hay không?

Trang 11

Java Mobile

void rebuild() Tự cập nhật lại enumeration

Sau đây là một ví dụ của lớp có cài đặt interface RecordComparator:

public class Comparator implements RecordComparator {

public int compare(byte[] rec1, byte[] rec2) {

String str1 = new String(rec1), str2 = new String(rec2);

int result = str1.compareTo(str2);

Chúng ta cài đặt interface này bằng cách cung cấp hàm int compare(byte[],byte[]) Hàm này trả về 3 giá trị đặc biệt đã được định nghĩa trước là:

Trang 12

Java Mobile

• RecordComparator.EQUIVALENT

• RecordComparator.PRECEDES

• RecordComparator.FOLLOWS Khi đó, để bắt đầu quá trình sắp xếp và xử lý dữ liệu ta tạo ra một đối tượng Comparator (lớp có cài đặt RecordComparator) và một RecordEnumeration:

// Tạo đối tượng Comparator để sắp xếp

Comparator comp = new Comparator();

// Tạo đối tượng enum, tham số thứ nhì là comparator

int compare (byte[] r1, byte[] r2) Tùy theo giá trị trả về của hàm mà record r1 sẽ được xếp trước record r2, xếp sau r2 hay 2 records được xem là “bằng nhau”

EQUIVALENT Record r1 và r2 được xem là bằng nhau, thực chất lúc này r1

được xếp trên r2 vì không có sự thay đổi thứ tự FOLLOWS Record r1 được xem là “lớn hơn” r2 và sẽ xếp sau

PRECEDES Record r1 được xem là “nhỏ hơn” r2 và sẽ xếp trước

Bảng 6.4 Các giá trị hằng để sắp xếp record

Trang 13

Java Mobile

Lúc này, khi ta dùng hàm enumerateRecords(…) của lớp RecordStore, kết quả trả về sẽ là một tập hợp (enum) đã được sắp thứ tự và ta có thể thao tác trên tập hợp này một cách bình thường

Nguyên lý sort thực chất cũng khá đơn giản: đối với những record gồm nhiều trường (compound record), khi chúng ta có nhu cầu chỉ search trên một trường bất

kỳ thì trước nhất phải đọc trường đó của 2 record cần so sánh ra 2 biến trung gian Sau đó việc so sánh 2 records trên thực chất là việc so sánh 2 biến trung gian Tùy theo nhu cầu sort ta sẽ gán giá trị trả về cho hàm compare của lớp Comparator một cách tương ứng

6.4 Lọc record với RecordFilter

Ngoài chức năng sắp xếp các record, J2ME còn hỗ trợ chúng ta công cụ lọc các record Phần vừa rồi chúng ta đề cập đến việc sắp xếp các record và đưa vào tập hợp, quá trình này ứng dụng sẽ sắp xếp tất cả các records có trong record store Nếu chúng ta chỉ có nhu cầu lấy ra và sắp xếp các record thỏa mãn một yêu cầu nhất định nào đó (ví dụ trường năm sinh trong record phải nhỏ hơn 1990) thì ta phải dùng thêm công cụ RecordFilter Cũng giống như RecordComparator, RecordFilter

là một interface, khi ta có nhu cầu lọc record thì ta phải cài đặt (implements) interface này qua hàm boolean matches(byte[] candidate)

Hàm matches(byte[] candidate) này nếu trả về giá trị true thì record candidate sẽ

có mặt trong RecordEnumeration, ngược lại nếu trả về giá trị false thì record sẽ bị loại

Giả sử ta có bài toán lọc theo năm sinh như sau: Trong một record sẽ có hai trường, trường HoTen được lưu dưới dạng String UTF8 và trường năm sinh lưu dưới dạng integer Ta cần lấy ra danh sách những người sinh trước năm 1990 Bài toán được giải quyết như sau:

public class YearFilter implements RecordFilter{

private int Year=1990;

Trang 14

public class MIDletApp extends MIDlet { …

Trang 15

Java Mobile

6.5 Nhận thông điệp khi Record Store thay đổi

Đôi khi chúng ta có nhu cầu cần được thông báo mỗi khi các records trong record store bị thay đổi, xóa hay được thêm vào Để phục vụ cho nhu cầu này, J2ME cung cấp cho chúng ta interface RecordListener Interface này hoạt động tương tự các interface chúng ta đã đề cập đến trong phần RMS này Khi lớp ứng dụng của ta cài đặt interface này, nếu có sự biến đổi nào trên các records của bộ record store chúng ta sẽ nhận được thông điệp thông qua các hàm recordAdded(), recordChanged() và recordDeleted()

Các hàm sự kiện trên đều có hai tham số:

• RecordStore recordStore: cho biết record store nào bị thay đổi

• int recordID: cho biết ID của record bị thay đổi

Trang 16

Java Mobile

6.6 Xử lý lỗi khi thao tác với Record Store

Hãng Sun đã đặt ra tổng cộng 5 exceptions dành riêng cho việc xử lý RMS Tất cả các exception này đều kế thừa từ lớp java.lang.Throwable, sau đây là danh sách các exception trên và ý nghĩa của chúng:

InvalidRecordIDException:

Được dùng để thông báo người dùng truy xuất đến RecordID không hợp lệ Ví dụ như khi hàm RecordStore.getRecord(int ID) được gọi và tham số ID bằng 0 thì exception này sẽ phát sinh

Trang 17

RecordStoreNotOpenException

Được phát sinh khi ta thực hiện một số công việc truy vấn trên record store như thêm record, xóa record, đếm số record mà record store chưa được mở trước đó Consturctor

public RecordStoreNotOpenException() public RecordStoreNotFoundOpen(String message)

Trang 18

Các nhà phát triển không đưa ra mục tiêu phát triển một bộ thư viện cung cấp các lớp, phương thức hoàn toàn mới mà họ muốn đưa ra một bộ thư viện con của các thư viện đã được phát triển khá tốt trên môi trướng J2SE và J2EE Bộ thư viện con này sẽ có một số thay đổi nhỏ để thích ứng với các hạn chế trên thiết bị di động cài đặt MIDP

7.2 Lược đồ lớp

Mục tiêu chung đươc đề ra là chúng ta cần có một lớp chính: lớp Connector Lớp này sẽ có khả năng tạo các loại kết nối khác nhau: http, datagram, file… Phương thức mở kết nối sẽ có dạng:

Trang 19

Java Mobile

Lúc này GCF cho thấy khả năng linh hoạt của mình Tùy theo các protocol khác nhau mà một kết nối loại tương ứng sẽ được mở và trả lại cho người dùng Lớp Connector sẽ tìm kiếm các lớp cài đặt cho loại protocol được yêu cầu, việc này được thực hiện thông qua phương thức Class.forName() Ví dụ khi có một yêu cầu

mở kết nối HTTP, lớp Connector sẽ thực thi hàm:

Class.forName(“com.sun.midp.io.j2me.http.Protocol”);

Sau khi kiểm tra, nếu lớp này tồn tại thì người dùng sẽ được trả lại một đối tượng cài đặt (implements) interface Connection và các thao tác truy cập sẽ được thực hiện thông qua đối tượng này Lớp Connector và interface Connection được định nghĩa trong CLDC

Lược đồ các lớp trong thư viện:

Hình 7.1 Lược đồ các lớp trong thư viện GCF

Thực chất CLDC chỉ cung cấp các định nghĩa cho các interface Quá trình cài đặt (implement) các protocols được thực hiện trong Profiles Ví dụ, trong MIDP 1.0 lớp HTTPConnection sẽ cài đặt (chỉ một phần) bộ giao thức HTTP 1.1 Lớp

Trang 20

Java Mobile

HTTPConnection cài đặt interface ContentConnection và có hơn 20 phương thức để

hỗ trợ người dùng tương tác với giao thức HTTP

Mặc dù DatagramConnection được biểu diển trên lược đồ nhưng MIDP 1.0 chỉ yêu cầu bắt buộc hỗ trợ giao thức HTTP Các nhà phát triển có thể hỗ trợ thêm các giao thức khác nhưng điều này không bắt buộc

Trong MIDP 2.0, chúng ta được hỗ trợ các phương thức kết nối thông qua TCP

và UDP Tuy nhiên, ở phần này chúng ta chú trọng đến việc kết nối thông qua HTTP, đây là yêu cầu bắt buộc với các thiết bị MIDP

Sau đây là danh sách các lớp,interfaces và hàm chính trong bộ GCF:

Connection (public abstract interface Connection)

public void close() InputConnection (public abstract interface InputConnection extends Connection)

public InputStream openInputStream() public DataInputStream openDataInputStream() OutputConnection (public abstract interface OutputConnection extends Connection)

public OutputStream openOutputStream() public DataOutputStream openDataOutputStream() StreamConnection (public abstract interface StreamConnection extends InputConnection, OutputConnection)

ContentConnection (public abstract interface ContentConnection extends StreamConnection)

public long getLength() public String getEncoding() public String getType() HttpConnection (public interface HttpConnection extends ContentConnection)

//Hơn 20 phương thức hỗ trợ truy cập HTTP Connector (public class Connector)

Trang 21

Java Mobile

public static Connection open(String name) public static Connection open(String name, int mode) public static Connection open(String name, int mode, boolean timeouts)

public static DataInputStream openDataInputStream(String name) public static DataOutputStream openDataOutputStream(String name) public static InputStream openInputStream(String name)

public static OutputStream openOutputStream(String name)

7.3.1 Khởi tạo kết nối:

Lớp Connector có 7 phương thức để khởi tạo kết nối với server

Lớp: javax.microedition.io.Connector

static Connection open(String name) Tạo connection dạng READ_WRITE

static Connection open(String name,

int mode)

Tạo connection với mode được chỉ định rõ (được đề cập ở bảng sau)

static Connection open(String name,

int mode, boolean timeouts)

Tạo connection với mode được chỉ định,

xử lý exception timeouts (được đề cập ở phần sau)

Trang 22

openOutputStream (String name)

Tạo một output stream cho connection

static DataInputStream

openDataInputStream (String name)

Tạo một data input stream cho connection

static DataOutputStream (String

Bảng 7.2 Mode Kết Nối

Trong 7 phương thức trên có 3 phương thức open() khác nhau: Phương thức đầu tiên chỉ đòi hỏi địa chỉ của server, phương thức thứ hai cho phép người dùng chọn kiểu connection có hỗ trợ reading/writing Phương thức cuối cùng cho phép người dùng tùy chọn có xử lý timeouts exception hay không Các phương thức còn lại dùng để mở các dòng dữ liệu đọc/ghi

Sau đây là đoạn lệnh dùng để thiết lập một kết nối kiểu ContentConnetion (đây

là interface cài đặt interface Connection và chứa các định nghĩa cho lớp HttpConnection, xin xem lại lược đồ bên trên):

String url = "http://www.mydomain.com"

ContentConnection connection = (ContentConnection) Connector.open(url);

Trang 23

InputStream iStrm = connection.openInputStream();

// ContentConnection hỗ trợ phương thức getLength

int length = (int) connection.getLength();

Thậm chí chúng ta còn có thể lấy ra dòng dữ liệu Input mà không cần tạo đối tượng connection như sau:

// Tạo một InputStream connection

String url = "http://www.mydomain.com/picture.png"

InputStream iStrm = (InputStream) Connector.openInputStream(url);

Trang 24

Java Mobile

Tuy nhiên, ở cách tiếp cận vừa nêu chúng ta không tận dụng được phương thức getLength() của interface ContentConnection Việc chọn lựa cách tiếp cận nào là tùy thuộc vào hoàn cảnh và sở thích của người lập trình

Đến thời điểm này chúng ta chỉ mới khởi tạo kết nối và đọc, ghi dữ liệu mà chưa tận dụng các tính năng liên quan đến giao thức HTTP HTTP là một giao thức dạng yêu cầu / phản hồi: client gửi một yêu cầu (request), server sẽ gửi lại một thông điệp phản hồi Tiếp theo chúng ta sẽ nghiên cứu những chức năng hỗ trợ giao thức HTTP

7.3.2 Các đặc điểm của kết nối HTTP bằng J2ME:

Các phương thức Yêu Cầu (Request):

Một yêu cầu từ phía client gồm 3 phần: phương thức request, header và phần thân (body) HttpConnection hỗ trợ ba phương thức request: GET, POST, HEAD

javax.microediton.io.HttpConnection

POST Thông tin yêu cầu được gửi theo một stream riêng biệt HEAD Gói tin yêu cầu truy vấn thông tin về một tài nguyên

Bảng 7.3 Các Request Method chính

Cả ba phương thức trên thông báo cho server biết client cần truy vấn một thông tin Phương thức GET và POST khác nhau ở cách thông tin truy vấn được gửi lên server

Chúng ta có thể chỉ định rõ phương thức sử dụng trong HttpConnection bằng hàm setRequestMethod():

HttpConnection http = null;

http = (HttpConnection) Connector.open(url);

http.setRequestMethod(HttpConnection.GET);

Trang 25

request (thuộc phần header)

Bảng 7.4 Các phương thức set/get Request Method

Sử dụng GET, phần thân của yêu cầu được đưa vào chung trong URL Điều này được gọi là URL encoding Ví dụ, chúng ta có một web form gồm 2 trường color và font Tên của hai trường này được đặt là userColor và userFont Khi user chọn giá trị cho hai trường này, giả sử lần lượt là userColor = blue và userFont = courier và submit lên trang web http://www.mydomain.com/formscript thì URL thực chất có dạng như sau:

http://www.mydomain.com/formscript?userColor=blue&userFont=courier (dấu ? dùng để phân cách vùng địa chỉ trang và phần thông tin yêu cầu gửi lên server) Sau đó, trang web trên server sẽ dùng các hàm riêng để tách vùng thông tin yêu cầu và thực hiện xử lý, sau đó sẽ trả kết quả cho client

Với phương thức POST, thông tin truy vấn không được ghép thêm vào vùng URL mà được chuyển lên server trong vùng BODY của gói tin HTTP

Phương thức POST có hai ưu điểm so với phương thức GET:

• Phương thức POST không giới hạn kích thước vùng dữ liệu request gửi lên server, ngược lại phương thức GET do gửi dữ liệu dạng gắn kèm vào URL nên không thể gửi kèm dữ liệu quá lớn

• POST gửi dữ liệu theo một dòng riêng (trong phần BODY) nên không thể hiện thông tin cho người dùng thấy trong URL

Trang 26

Java Mobile

HEAD là một phương thức gần giống với GET Client gửi dữ liệu lên server và đính kèm nó với URL Tuy nhiên, trong gói tin hồi đáp của server cho gói tin dạng HEAD này sẽ không có vùng BODY HEAD được dùng chủ yếu để lấy thông tin về một tài nguyên nào đó trên server Ví dụ, chúng ta muốn lấy thông tin về lần cập nhật mới nhất của một tập tin trên server, do đó, trong gói tin trả lời chúng ta thực chất không cần nội dung của file trên (gói tin không có vùng BODY)

Ghi chú: Luận văn không có mục tiêu trình bày về giao thức HTTP mà chỉ giới thiệu HTTP như một phương thức kết nối được J2ME hỗ trợ, do đó phần lý thuyết giới thiệu về HTTP sẽ rất hạn chế Nếu người đọc muốn tìm hiểu hơn về HTTP có thể tìm đọc RFC 2616 về HTTP 1.1

Thông tin Header:

Phần thứ hai của một gói tin yêu cầu từ client là phần header Giao thức HTTP định nghĩa hơn 40 trường header Một số trường thông dụng như Accept, Cache-Control, Content-Type, Expires, If-Modified-Since và User-Agent Header được đặt giá trị bằng hàm setRequestProperty() đã được đề cập bên trên

Gói tin trả lời của Server:

Trang 27

Java Mobile

Khi client đã đóng gói một gói tin gồm phương thức yêu cầu, phần header, phần body và gửi đến server, server có trách nhiệm phân tích gói tin, xử lý và hồi đáp client Phần hồi đáp của server cũng gồm 3 phần: status line, header và phần body

Status Line:

Phần status line cho biết kết quả của gói tin yêu cầu từ phía client Trong HttpConnection, chúng ta có hơn 35 mã status hồi đáp HTTP chia các mã hồi đáp này thành 5 mục lớn:

1xx – Thông tin 2xx – Mã báo thành công 3xx – Chuyển hướng (redirection) 4xx – Lỗi từ phía client

5xx – Lỗi tại server

Ví dụ, HTTP_OK (mã 200) thông báo yêu cầu từ phía client đã được xử lý thành công Khi gửi gói tin hồi đáp (response), server thường gửi cả version của giao thức kèm theo status line

Đây là một số ví dụ về status line:

HTTP/1.1 200 OK HTTP/1.1 400 Bad Request HTTP/1.1 500 Internal Server Error

Khi đọc mã status, ta có hai lựa chọn: lấy về mã hay câu thông báo:

Trang 28

Java Mobile

javax.microedition.io.HttpConnection

String getHeaderField(int n) Lấy giá trị 1 trường header theo index

String getHeaderField(String name) Lấy giá trị 1 trường header theo tên

Bảng 7.5 Các phương thức truy vấn HTTP Header

Xét một ví dụ, giả sử trong vùng header ta có một cặp khóa/giá trị như sau: content-type=text/plain (“content-type” là một trường được HTTP định nghĩa,

“text-plain” để chỉ giá trị trả về có dạng text đơn thuần) Chúng ta giả sử thêm trường content-type này là trường đầu tiên (index=0) trong vùng header Để lấy giá trị của trường này ta có những cách sau:

Trang 29

Ứng dụng Client sẽ trải qua một số bước:

//Gửi yêu cầu lên server:

//1) Xác định phương thức yêu cầu là GET

http.setRequestMethod(HttpConnection.GET);

//2) Gửi các thông tin header (không bắt buộc phải có)

http.setRequestProperty(“User-Agent”, “Profile/MIDP-1.0 1.0");

Configuration/CLDC-//3) Gửi dữ liệu, vì dùng Get nên không có phần body – data

Sau đó chúng ta phải xử lý phần thông tin trả về của server để lấy ra nội dung file

//Thông tin trả về của server //1) Lấy status line:

Ngày đăng: 12/08/2014, 10:20

HÌNH ẢNH LIÊN QUAN

Bảng 6.1 Mô hình Record Store - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 6.1 Mô hình Record Store (Trang 1)
Bảng 6.2 Lớp RecordStore - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 6.2 Lớp RecordStore (Trang 3)
Hình 7.1 Lược đồ các lớp trong thư viện GCF - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Hình 7.1 Lược đồ các lớp trong thư viện GCF (Trang 19)
Bảng 7.1 Lớp Connector - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.1 Lớp Connector (Trang 22)
Bảng 7.4 Các phương thức set/get Request Method - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.4 Các phương thức set/get Request Method (Trang 25)
Bảng 7.5 Các phương thức truy vấn HTTP Header - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.5 Các phương thức truy vấn HTTP Header (Trang 28)
Bảng 7.6 Lấy thông số kết nối - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.6 Lấy thông số kết nối (Trang 31)
Hình 7.2 Kết nối UDP - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Hình 7.2 Kết nối UDP (Trang 32)
Bảng 7.7 Lớp DatagramConnection - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.7 Lớp DatagramConnection (Trang 33)
Bảng 7.8 Lớp Datagram - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.8 Lớp Datagram (Trang 34)
Hình 7.3 Kết Nối TCP - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Hình 7.3 Kết Nối TCP (Trang 35)
Bảng 7.9 Thuộc tính của SocketConnection - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Bảng 7.9 Thuộc tính của SocketConnection (Trang 36)
Hình 7.4 Lược đồ lớp thư viện WMA  Khởi tạo kết nối SMS: - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Hình 7.4 Lược đồ lớp thư viện WMA Khởi tạo kết nối SMS: (Trang 39)
Hình 8.2 Một client truy xuất đến nhiều web services cùng lúc - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Hình 8.2 Một client truy xuất đến nhiều web services cùng lúc (Trang 48)
Hình 8.3 Một web service có thể triệu tập đến các web services khác - Nghiên cứu JM và xây dựng ứng dụng minh họa (Đặng Nguyễn Kim Anh vs Đào Anh Tuấn) - 3 potx
Hình 8.3 Một web service có thể triệu tập đến các web services khác (Trang 49)

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w