Label

Thứ Năm, 7 tháng 4, 2011

Giới thiệu về JSP và Servlet (phần 3)

Giới thiệu về JSP và Servlet (phần 3)
Phần này giới thiệu về Request và Response, hai thành phần quan trọng trong Servlet
Các đối tượng request và response
Phương thức doGet có hai tham số HTTPServletRequest và HTTPServletResponse. Hai đối tượng này cho phép chúng ta truy cập đầy đủ tất cả các thông tin về yêu cầu và cho phép chúng ta gởi luồng xuất cho client như là trả lời cho yêu cầu.
Với CGI bạn đọc các biến môi trường và stdin để nhận thông tin về yêu cầu, tuy nhiên việc đặt tên các biến môi trường có thể khác nhau giữa các CGI, và một vài biến không được cung cấp bởi tất cả các Web server.
Đối tượng HTTPServletRequest cũng cung cấp thông tin giống như biến môi trường của CGI theo một hướng chuẩn. Nó cũng cung cấp những phương thức để mở ra các tham số HTTP từ chuỗi truy vấn hoặc thân của yêu cầu phụ thuộc vào kiểu yêu cầu (GET hay POST). Là một nhà phát triển servlet, bạn truy cập các tham số theo cùng một cách cho cả hai kiểu yêu cầu. Những phương thức khác cho bạn truy cập đến tất cả những header của yêu cầu và giúp bạn phân tích các header ngày và cookie.
Thay vì viết trả lời như stdout giống như bạn làm với CGI, bạn nhận một đối tượng OutputStream hoặc PrintWriter từ HTTPServletResponse. OutputStream được dành cho dữ liệu nhị phân như các ảnh GIF hoặc JPEG, và PrintWriter dành cho việc xuất văn bản text. Bạn cũng có thể ấn định tất cả các header trả lời và mã trạng thái mà không phải phụ thuộc vào các cấu hình cụ thể của Web server CGI nào. Điều này làm cho servlet của bạn dễ dàng cài đặt.
Hãy bổ sung vào thân của phương thức doGet và xem chúng ta sử dụng những phương thức này như thế nào. Chúng ta có thể đọc hầu hết các thông tin chúng ta có được từ HTTPServletRequest (lưu những phương thức này vào ví dụ kế tiếp) và gởi những giá trị này để trả lời cho yêu cầu

protected void doGet(HttpServletRequest request, HttpServletResponse response)                                                                          throws ServletException, IOException {
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();
// in ra HTML header
out.println(“”);
out.println(“Request info”);
out.println(“”);
// in ra than HTML
out.println(“

Request info

”);
out.println(“getCharacterEncoding: ” +    request.getCharacterEncoding());
out.println(“getContentLength: ” + request.getContentLength());
out.println(“getContentType: ” + request.getContentType());
out.println(“getProtocol: ” + request.getProtocol());
out.println(“getRemoteAddr: ” + request.getRemoteAddr());
out.println(“getRemoteHost: ” + request.getRemoteHost());
out.println(“getScheme: ” + request.getScheme());
out.println(“getServerName: ” + request.getServerName());
out.println(“getServerPort: ” + request.getServerPort());
out.println(“getAuthType: ” + request.getAuthType());
out.println(“getMethod: ” + request.getMethod());
out.println(“getPathInfo: ” + request.getPathInfo());
out.println(“getPathTranslated: ” + request.getPathTranslated());
out.println(“getQueryString: ” + request.getQueryString());
out.println(“getRemoteUser: ” + request.getRemoteUser());
out.println(“getRequestURI: ” + request.getRequestURI());
out.println(“getServletPath: ” + request.getServletPath());
out.println();
out.println(“Parameters:”);
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String name = (String) paramNames.nextElement();
String[] values = request.getParameterValues(name);
out.println(” ” + name + “:”);

for (int i = 0; i < values.length; i++) {
out.println(” ” + values[i]);
}
}

out.println();
out.println(“Request headers:”);
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = (String) headerNames.nextElement();
String value = request.getHeader(name);
out.println(” ” + name + ” : ” + value);
}

out.println();
out.println(“Cookies:”);
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
String name = cookies[i].getName();
String value = cookies[i].getValue();
out.println(” ” + name + ” : ” + value);
}

// in ra footer HTML
out.println(“
”); out.close(); } Phương thức doGet ở trên sử dụng hầu hết các phương thức trong HTTPServletRequest nhằm cung cấp thông tin về yêu cầu. Bạn có thể đọc chúng trong tài liệu servlet API, vì thế ở đây chúng ta chỉ tìm kiếm những gì đáng chú ý nhất. getParameterNames và getParameterValues giúp bạn truy cập những tham số HTTP nếu servlet được yêu cầu với phương thức GET hay post. getParameterValues trả về một dãy String bởi vì một tham số có thể có nhiều giá trị. Ví dụ nếu bạn yêu cầu servlet với một chuỗi URL http://localhost:8080/servlet/ReqInfoServlet?foo=bar&foo=baz thì bạn sẽ thấy tham số foo có hai giá trị bar và baz. Điều này đúng nếu như bạn sử dụng chung một tên định danh cho nhiều thành phần của form HTML và sử dụng phương thức POST trong thẻ ACTION. Nếu như bạn chắc chắn rằng một tham số HTTP chỉ có thể có một giá trị thì bạn có thể sử dụng phương thức getParameter thay vì getParameterValues. Nó trả về một chuỗi String và nếu có nhiều giá trị nó sẽ trả về giá trị đầu tiên nhận được từ yêu cầu. Bạn truy cập đến tất cả header của yêu cầu HTTP với các phương thức getHeaderNames và getHeader. getHeader trả về một chuỗi String của header. Nếu như bạn biết header có chứa giá trị ngày hay một giá trị integer bạn có thể nhận được sự giúp đỡ chuyển đổi header sang một định dạng tương thích. getDateHeader trả về một ngày là số mili giây bắt đầu từ 00:00:00 GMT . ngày 1/1/1970. Đây là sự thay thế số chuẩn cho thời gian trong Java (tương tự như Unix). Bạn có thể sử dụng nó để khởi dựng một đối tượng ngày. getIntHeader trả về header giá trị kiểu int. getCookie sẽ phân tích Cookie và trả về tất cả cookie trong một dãy các đối tượng Cookie. Để thêm một cookie vào trả lời, HTTPServletResponse cung cấp phương thức addCookie đặt một đối tượng Cookie như là một đối số. Nếu như bạn biên dịch ReqInfoServlet và cài đặt nó trên servlet engine của bạn và gọi nó thông qua trình duyệt với một URL giống như và mọi thứ đều đúng theo sau http://localhost:8080/servlet/ReqInfoServlet/foo/bar?fee=baz thì trong trình duyệt sẽ hiển thị Request info getCharacterEncoding: getContentLength: -1 getContentType: null getProtocol: HTTP/1.0 getRemoteAddr: 127.0.0.1 getRemoteHost: localhost getScheme: http getServerName: thangnc getServerPort: 8080 getAuthType: null getMethod: GET getPathInfo: /foo/bar getPathTranslated: D:\PROGRA~1\jsdk2.1\httproot\servlet\ReqInfoServlet\foo\bar getQueryString: fee=baz getRemoteUser: null getRequestURI: /servlet/ReqInfoServlet/foo/bar getServletPath: /servlet/ReqInfoServlet Parameters: fee: baz Request headers: Connection : Keep-Alive User-Agent : Mozilla/4.5 [en] (WinNT; I) Host : thangnc Accept : image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding : gzip Accept-Language : en Accept-Charset : iso-8859-1,*,utf-8 Cookie : TOMCATID=TO04695278486734222MC1010AT Cookies: TOMCATID : TO04695278486734222MC1010AT Nếu bạn muốn servlet này xử lý cả yêu cầu GET và POST? Việc bổ sung mặc định doGet và doPost trả về một thông điệp thông báo rằng phương thức này chưa được bổ sung. Vì thế chúng ta chỉ phải cung cấp một bổ sung mới của doGet. Để có thể xử lý một yêu cầu POST theo cùng một cách, chúng ta chỉ cần gọi doGet từ doPost protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }

http://blackdiamond89.wordpress.com/2009/09/06/gi%E1%BB%9Bi-thi%E1%BB%87u-v%E1%BB%81-jsp-va-servlet-ph%E1%BA%A7n-3/

1 nhận xét:

  1. Một trong những đặc điểm thú vị của Servlet API là hỗ trợ persistent data. Khi một servlet đã được tải theo các request và các servlet đã được tải vào trong cùng một xử lý, điều đó dễ dàng nhớ thông tin từ một request này đến một request khác và đến những servlet chia sẻ dữ liệu khác nhau.
    // <![CDATA[//
    // <![CDATA[//
    Dữ liệu chia sẻ và cố định (Persistent and shared data)
    Một trong những đặc điểm thú vị của Servlet API là hỗ trợ persistent data. Khi một servlet đã được tải theo các request và các servlet đã được tải vào trong cùng một xử lý, điều đó dễ dàng nhớ thông tin từ một request này đến một request khác và đến những servlet chia sẻ dữ liệu khác nhau.
    Servlet API chứa một số các kỹ thuật để hỗ trợ điều này một cách trực tiếp. Chúng ta sẽ xem xét về chúng một cách chi tiết dưới đây. Một cách hữu hiệu khác xử lý dữ liệu được chia sẻ bằng cách sử dụng một đối tượng singleton.
    Một lớp HttpSession đã được giới thiệu trong phiên bản 2.0 của Servlet API. Các thực thể của lớp này có thể nắm giữ thông tin về một session của người dùng giữa những yêu cầu khác nhau. Bạn bắt đầu một session mới bằng việc yêu cầu một đối tượng HttpSession từ lớp HttpServletRequest trong phương thức doGet hay doPost của bạn:

    HttpSession session = request.getSession(true);

    Phương thức này đặt vào một đối số kiểu boolean. Nếu đối số được đặt vào là true thì sẽ có một session mới được tạo ra nếu nó chưa tồn tại. Nếu đối số được đặt vào là false thì chỉ có một session tồn tại được trả về. Servlet API hỗ trợ hai cách để tập hợp nhiều request vào một session: cookie và ghi đè vào URL (URL rewriting).
    Nếu cookie được sử dụng, một cookie với định danh session ID duy nhất được gởi đến client khi một session được tạo ra. Khi đó, client bao gồm cookie với tất cả request liên tục để servlet engine có thể tính toán session nào thì request được đi kèm. URL rewriting được thiết kế cho các client không hỗ trợ cookie hoặc khi người dùng không cho phép cookie.
    Với URL rewriting, cookie sẽ được mã hóa trong các URL để servlet của bạn gởi đến cho client. Khi người dùng click vào một URL đã được mã hóa, session ID sẽ được gởi đến server, nơi nó được giải mã và phải tập hợp request của client với session đúng. Để sử dụng URL rewriting, bạn phải chắc chắn rằng tất cả các session được gởi đến client phải được mã hóa với phương thức encodeURL hoặc encodeRedirectURL trong HttpServletResponse.
    Một HttpSession có thể lưu trữ bất kỳ một kiểu đối tượng nào. Một ví dụ thông dụng là một kết nối database cho phép nhiều request được đặt trong cùng một chuyển đổi database, hoặc là thông tin về sản phẩm đã được mua trong một ứng dụng Shopping cart cho phép người dùng có thể thêm vào một mặt hàng trong giỏ hàng của họ trong khi vẫn duyệt qua site. Để lưu một đối tượng trong một HttpSession, bạn dùng phương thức putValue


    Connection con = driver.getConnection(databaseURL, user, password);
    session.putValue(“myApp.connection”, con);


    Trong một servlet khác hoặc trong cùng một servlet nhưng xử lý một request khác, bạn có thể lấy đối tượng với phương thức getValue


    HttpSession session = request.getSession(true);
    Connection con = (Connection) session.getValue(“myApp.connection”);

    if(con != null) {
    // Thực thi những chuyển đổi dữ liệu

    }

    Bạn có thể ngừng tương đối (làm mất hiệu lực) một session bằng một phương thức vô hiệu hóa hoặc để nó kết thúc (time-out) một cách tự động bằng servlet engine. Session kết thúc nếu không có một request nào đi kèm với session trong một khoảng thời gian xác định. Hầu hết các servlet engine đều cho phép bạn xác định độ dài của khoảng thời gian đó thông qua một lựa chọn cấu hình. Trong phiên bản 2.1 của Servlet API cũng kèm theo một phương thức setMaxInactiveInterval vì thế cho phép bạn chỉnh sửa thời gian để tương thích với các yêu cầu của mỗi ứng dụng cụ thể.

    Trả lờiXóa