Hỗ trợ giao thức HTTP trong MIDP
Đến đây thì bạn dã biết được rằng GCF hỗ trợ nhiều kiểu kết nối và đã phát triển ứng dụng MIDlet tải về và hiển thị hình ảnh. Trong phần này, sẽ bàn sâu hơn về sự hỗ trợ HTTP của GCF. Đầu tiên, hãy cập nhật lại sơ đồ quan hệ giữa các interfaces trong ...
Đến đây thì bạn dã biết được rằng GCF hỗ trợ nhiều kiểu kết nối và đã phát triển ứng dụng MIDlet tải về và hiển thị hình ảnh. Trong phần này, sẽ bàn sâu hơn về sự hỗ trợ HTTP
của GCF. Đầu tiên, hãy cập nhật lại sơ đồ quan hệ giữa các interfaces trong GCF để thấy
được vị trí của http:
Đặc tả của phiên bản MIDP 1.0 chỉ hỗ trợ HTTP, trong khi đó phiên bản hiện tại MIDP
2.0 hỗ trợ HTTP và HTTPS, cung cấp khả năng bảo mật tốt hơn. Các hàm API được khai báo trong HttpConnection (cho HTTP) và trong HttpConnections (cho HTTP và HTTPS).
a) Request and response protocols
Cả HTTP và HTTPS đều gửi request và response. Máy client gửi request, còn server sẽ trả về response.
Client request bao gồm 3 phần sau:
• Request method
• Header
• Body
Request method định nghĩa cách mà dữ liệu sẽ được gửi đến server. Có 3 phương thức được cung cấp sẵn là GET, POST, HEADER. Khi sử dụng Get, dữ liệu cần request sẽ nằm trong URL. Với Post dữ liệu gửi từ client sẽ được phân thành các stream riêng biệt. Trong khi đó, Header sẽ không gửi dữ liệu yêu cầu lên server, thay vào đó header chỉ request những meta information về server. GET và POST là hai phương thức request khá giống nhau, tuy nhiên do GET gửi dữ liệu thông qua URL nên sẽ bị giới hạn, còn POST sử dụng những stream riêng biệt nên sẽ khắc phục được hạn chế này.
Ví dụ về việc mở HTTP Connection thông qua GET String url = "http://www.corej2me.com?size=large"; HttpConnection http = null;
http = (HttpConnection) Connector.open(url);
http.setRequestMethod(HttpConnection.GET);
Những Header field sẽ cho phép ta truyền các tham số từ client đến server. Các header field thường dùng là If-Modified-Since, Accept, and User Agent. Bạn có thể đặt các
field này thông qua phương thức setRequestProperty(). Dưới đây là ví dụ dùng setRequestProperty(), chỉ có những dữ liệu thay đổi sau ngày 1 tháng 1 năm 2005 mới được gửi về từ server:
String url = "http://www.corej2me.comsomefile.txt"; HttpConnection http = null;
http = (HttpConnection) Connector.open(url);
http.setRequestMethod(HttpConnection.GET);
// Set header field as key-value pair
http.setRequestProperty("If-Modified-Since", "Sat, 1 Jan 2005 12:00:00 GMT");
Body chứa nội dung mà bạn muốn gửi lên server. Ví dụ về sử dụng POST và gửi dữ liệu từ
client thông qua stream:
String url = "http://www.corej2me.com",
tmp = "test data here"; OutputStream ostrm = null; HttpConnection http = null;
http = (HttpConnection) Connector.open(url);
http.setRequestMethod(HttpConnection.POST);
// Send client body
ostrm = http.openOutputStream(); byte bytes[] = tmp.getBytes(); for(int i = 0; i < bytes.length; i++)
{
os.write(bytes[i]);
}
os.flush();
Sau khi nhận được và sử lý yêu cầu từ phía client, server sẽ đóng gói và gửi về phía client. Cũng như client request, server cũng gồm 3 phần sau:
• Status line
• Header
• Body
Status line sẽ thông báo cho client kết quả của request mà client gửi cho server. HTTP phân loại status line thành các nhóm sau đây:
• 1xx is informational
• 2xx is success
• 3xx is redirection
• 4xx is client error
• 5xx is server error
Status line bao gồm version của HTTP trên server, status code, và đoạn text đại diện cho status code. Ví dụ:
"HTTP/1.1 200 OK"
"HTTP/1.1 400 Bad Request"
"HTTP/1.1 500 Internal Server Error"
Header. Không giống như header của client, server có thể gửi data thông qua header. Sau đây là những phương thức dùng để lấy thông tin Header mà server gửi về:
String getHeaderField(int n) Get header field value looking up by index
String getHeaderField(String name) Get header field value looking up by name
String getHeaderFieldKey(int n) Get header field key using index
Server có thể trả về nhiều Header field. Trong trường hợp này, phương thức đầu tiên sẽ cho lấy header field thông qua index của nó. Còn phương thức thứ hai lấy nội dung header field dựa vào tên của header field. Còn nếu muốn biết tên (key) của header field, có thể dùng phương thức thứ 3 ở trên.
Sau đây là ví dụ về 3 phương thức trên, trong trường hợp server gửi về chuỗi
"content-type=text/plain".
![](/pictures/picfullsizes/2018/05/24/axn1527146149.jpg)
Body: Cũng giống như client, server gửi hầu hết những thông tin trong phần body cho client. Client dùng input stream để đọc kết quả trả về từ server.
b) The HttpConnection API
Như đã đề cập ở trên, ta sẽ sử dụng HttpConnection API để thiết lập kết nối trong
MIDP. Dưới đây là những API trong HttpConnection:
Ví dụ: Chúng ta sẽ tạo một MIDlet sử dụng HttpConnection để tải về và hiển thị nội dung của file text. Qua ví dụ bạn sẽ hiểu cách client gửi request và lấy response của server. MIDlet cũng sử dụng một số phương thức trong HttpConnection để thu thập thông tin về server: port, content type .. .
/*--------------------------------------------------
* FileViewer.java
*-------------------------------------------------*/ import javax.microedition.midlet.*; import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class FileViewer extends MIDlet implements CommandListener
{
private Display display;
private Form fmMain;
private Command cmExit;
private Command cmView;
private String url = "http://localhost/text.txt";
public FileViewer()
{
display = Display.getDisplay(this);
// Create exitcommand
cmExit = new Command("Exit", Command.EXIT, 1);
cmView = new Command("View", Command.SCREEN, 2);
// Create the form and add commands
fmMain = new Form("File Viewer");
fmMain.addCommand(cmExit);
fmMain.addCommand(cmView);
fmMain.setCommandListener(this);
}
public void startApp()
{
display.setCurrent(fmMain);
}
/*--------------------------------------------------
* Process events
*-------------------------------------------------*/
public void commandAction(Command c, Displayable s)
{
// If the Command button pressed was "Exit"
if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
else if (c == cmView)
{
// Download image and place on the form
try
{
String str;
if ((str = readFile()) != null)
{
// Delete form contents
for (int i = fmMain.size(); i > 0; i--)
fmMain.delete(0);
// Append downloaded string
fmMain.append("" + str);
}
}
catch (Exception e)
{
System.err.println("Msg: " + e.toString());
}
}
}
/*--------------------------------------------------
* Read file
*-------------------------------------------------*/
private String readFile() throws IOException
{
HttpConnection http = null;
InputStream iStrm = null;
String str = null;
try
{
// Create the connection
http = (HttpConnection) Connector.open(url);
//----------------
// Client Request
//----------------
// 1) Send request method
http.setRequestMethod(HttpConnection.GET);
// 2) Send header information (this header is optional)
http.setRequestProperty("User-Agent", "Profile/MIDP-1.0 Configuration/CLDC-1.0");
// 3) Send body/data - No data for this request
//----------------
// Server Response
//----------------
System.out.println("url: " + url);
System.out.println("-------------------------");
// 1) Get status Line
System.out.println("Msg: " + http.getResponseMessage());
System.out.println("Code: " + http.getResponseCode());
System.out.println("-------------------------");
// 2) Get header information
if (http.getResponseCode() == HttpConnection.HTTP_OK)
{
System.out.println("key 0: " + http.getHeaderFieldKey(0));
System.out.println("key 1 : " + http.getHeaderFieldKey(1));
System.out.println("key 2: " + http.getHeaderFieldKey(2));
System.out.println("-------------------------");
System.out.println("value (field) 0: " + http.getHeaderField(0));
System.out.println("value (field) 1: " + http.getHeaderField(1));
System.out.println("value (field) 2: " + http.getHeaderField(2));
System.out.println("-------------------------");
// 3) Get data (show the file contents)
iStrm = http.openInputStream();
int length = (int) http.getLength();
if (length != -1)
{
// Read data in one chunk
byte serverData[] = new byte[length];
iStrm.read(serverData);
str = new String(serverData);
}
else // Length not available...
{
ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
// Read data one character at a time
int ch;
while ((ch = iStrm.read()) != -1)
bStrm.write(ch);
str = new String(bStrm.toByteArray());
bStrm.close();
}
//-----------------------------
// Show connection information
//-----------------------------
System.out.println("Host: " + http.getHost());
System.out.println("Port: " + http.getPort());
System.out.println("Type: " + http.getType());
}
}
finally
{
// Clean up
if (iStrm != null)
iStrm.close();
if (http != null)
http.close();
}
return str;
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional)
{
}
}
Output
Console output
![](/pictures/picfullsizes/2018/05/24/qxk1527146149.jpg)