Bài 7 Xử lý biến session

Giao thức HTTP là giao thức phi trạng thái (stateless protocol). Khi một lời yêu cầu (request) được tạo ra từ client thì một kết nối (connection) được mở ra, đáp ứng (response) gửi từ server xuống client. Sau đó, kết nối được đóng lại ngay

pdf60 trang | Chia sẻ: lylyngoc | Lượt xem: 2068 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Bài 7 Xử lý biến session, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1LẬP TRÌNH ỨNG DỤNG MẠNG BÀI 7 XỬ LÝ BIẾN SESSION GIẢNG VIÊN: VÕ TẤN DŨNG TRƯỜNG CAO ĐẲNG CÔNG NGHỆ THÔNG TIN TP.HCM G V : V õ T ấ n D ũ n g 2PHẦN 1 KHÁI NIỆM SESSION G V : V õ T ấ n D ũ n g 3HTTP là giao thức phi trạng thái G V : V õ T ấ n D ũ n g y Giao thức HTTP là giao thức phi trạng thái (stateless protocol). Khi một lời yêu cầu (request) được tạo ra từ client thì một kết nối (connection) được mở ra, đáp ứng (response) gửi từ server xuống client. Sau đó, kết nối được đóng lại ngay. y Nếu một transaction (giao tác) thực hiện một chuỗi liên tiếp các request/response liên tiếp thì hậu quả là Web Server không nhớ được các bước request/response trước đó. y Ví dụ, khi ta mua sắm online, ta chọn các mặt hàng xong thì chuyển sang trang tính tiền. Lúc này Web Server không nhớ trước đó ta đã chọn mặt hàng nào. 4Khái niệm session G V : V õ T ấ n D ũ n g y Ta đã nhận rõ một điều rằng trong dịch vụWeb không có kết nối duy trì thường xuyên giữa trình khách (web browser) và trình chủ (web server). y Khi trình duyệt cần trình chủ cung cấp một trang tài liệu, trình duyệt mở kết nối, lấy về trang dữ liệu và sau đó đóng kết nối ngay lập tức. Vì vậy Web Server sẽ không biết được trước đó trình duyệt đã có những trạng thái nào. y Session tượng trưng một giai đoạn duy trì kết nối giữa trình khách và trình chủ trong quá trình liên lạc. Một loạt các request từ một client sẽ được liên kết với một session. 5Khái niệm session G V : V õ T ấ n D ũ n g y Như vậy, làm thế nào để server nhớ được các giao tác xảy ra trước đó của một client bất kỳ? Ta có thể theo dõi các phiên làm việc (session tracking) của một web client bằng các cách sau: y Lưu dữ liệu trong các biến ẩn của form (hidden fields). y Lưu dữ liệu trong đối tượng session. y Lưu dữ liệu trong bảng băm (hash table) y Lưu dữ liệu toàn cục của ứng dụng web trong đối tượng application. 6PHẦN 2 HIDDEN FORM FIELDS G V : V õ T ấ n D ũ n g 7HIDDEN FORM FELDS G V : V õ T ấ n D ũ n g y Ý tưởng ở đây là mỗi khi người dùng thực hiện thao tác submit một form, form sẽ chứa một số biến ẩn chứa thông tin trạng thái hoặc liên quan đến người dùng đang tương tác với ứng dụng. y Trở ngại lớn nhất của phương pháp này là chương trình luôn phải truyền các biến ẩn liên tục giữa các trang có liên hệ với nhau. y Ví dụ: ta hãy xem ví dụ ở slide sau đây. Mục đích của ví dụ này là giữ lại thông tin username để các trang khác truy cập. 8Login.html G V : V õ T ấ n D ũ n g Login Please log in User Name: Password: 9HIDDEN FORM FELDS G V : V õ T ấ n D ũ n g 10 File Login.jsp G V : V õ T ấ n D ũ n g <% //Lay cac thong tin dang nhap String userName=request.getParameter("username"); String password=request.getParameter("password"); %> Welcome, ! "> Please enter your favorite book: C/C++ Java Linux XML .NET Platform 11 File Login.jsp G V : V õ T ấ n D ũ n g y A 12 File BookServlet.java G V : V õ T ấ n D ũ n g import javax.servlet.*; import java.io.*; public class BookServlet extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out=response.getWriter(); String userName=request.getParameter("username"); String book = request.getParameter("book"); out.println(""); out.println(""); out.println("Well, I see that "+userName+"'s favorite book is "+ book +"."); out.println(""); out.println(""); } } 13 File BookServlet.java G V : V õ T ấ n D ũ n g y Ví dụ trên cho ta thấy, thông tin hay giá trị của username được nhập vào từ trang Login.html truyền cho trang Login.jsp. Trang Login.jsp lưu giá trị này trong biến ẩn của form và chuyển tiếp cho Servlet. Quá trình cứ thế tiếp diễn cho đến khi nào bạn thôi không còn muốn sử dụng thông tin của username nữa. 14 PHẦN 3 SỬ DỤNG HASH TABLE (dùng để bảo mật các biến ẩn của Form) G V : V õ T ấ n D ũ n g 15 SỬ DỤNG HASH TABLE G V : V õ T ấ n D ũ n g y Một trong những lý do mà biến ẩn của Form không được sử dụng nhiều trong các ứng dụng Web thương mại nhất là các site e-commerce đó là tính không bảo mật của giá trị và tên biến. y Với ví dụ BookServlet của các slide trước, người dùng có thể đánh lừa BookServlet bằng cách dùng trình duyệt xem code HTML mà BookServlet gửi xuống và dễ dàng nhận thấy có biến ẩn username. Sau đó người dùng có thể truyền trực tiếp giá trị cho username ngay trên đường dẫn: y 16 SỬ DỤNG HASH TABLE G V : V õ T ấ n D ũ n g y Để giải quyết tính không bảo mật của các biến ẩn trong Form, ta dùng cơ chế bảng băm (Hash Table). y Khi việc chứng thực username/password thành công, bạn sinh ra một khóa ngẫu nhiên tương ứng với username. Khóa này được đặt trong biến ẩn của Form đồng thời lưu giá trị thực tế của biến username và khóa trong đối tượng bảng băm trên server. y Lần kế tiếp người dùng chuyển biến ẩn lên server, trang JSP hay Servlet của ta không chuyển giá trị của username mà chuyển giá trị của khóa tương ứng với nó. Có giá trị khóa, thực hiện dò trong bảng băm ta sẽ tìm ra được giá trị của biến username. 17 File UserDatatable.java G V : V õ T ấ n D ũ n g y Đối tượng bảng băm dùng sinh khóa và lưu dữ liệu cho biến được cài đặt thành lớp UserDataTable như sau: /* UserDataTable.java */ package storage; import java.util.*; public class UserDataTable { protected static Hashtable userData=new Hashtable(); protected static Random keyGenerator = new Random(); public static String createUserData() { String userKey=""+keyGenerator.nextLong(); userData.put(userKey, new Hashtable()); return userKey; } public static Hashtable getUserData(String userKey) { if(userKey==null) return null; return (Hashtable)userData.get(userKey); } public static void clearUserData(String userKey) { if(userKey==null) return; userData.remove(userKey); } } 18 File Login2.jsp G V : V õ T ấ n D ũ n g y Trang Login2.jsp sau đây thay vì lưu nội dung username vào biến ẩn của Form, chúng ta gọi UserDataTable sinh khóa và lưu khóa vào biến Form ẩn. <% String userName=request.getParameter("username"); String password=request.getParameter("password"); String userKey=storage.UserDataTable.createUserData(); Hashtable userData=storage.UserDataTable.getUserData(userKey); userData.put("username", userName); %> Welcome, ! "> Please enter your favorite Book: C/C++ Java Linux XML .NET Platform 19 File BookServlet2.java G V : V õ T ấ n D ũ n g y Dưới đây là mã nguồn của BookServlet2.jsp thay thế cho BookServlet. BookServlet nhận giá trị khóa, tìm dữ liệu tương ứng của khóa trong bảng băm và in ra kết xuất. /* BookServlet2.java */ package storage; import javax.servlet.*; import java.io.*; import java.util.*; public class NewServlet /*BookServlet2*/ extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String userKey=request.getParameter("userkey"); String book=request.getParameter("book"); Hashtable userData=storage.UserDataTable.getUserData(userKey); 20 File BookServlet2.java G V : V õ T ấ n D ũ n g if(userData==null) { out.println(""); out.println("Sorry"); out.println("The system is experiencing problems."); out.println(""); return; } String userName=(String)userData.get("username"); out.println(""); out.println(""); out.println("Well, I see that "+userName+"'s favorite book is "+book+"."); out.println(""); out.println(""); } } 21 PHẦN 4 SỬ DỤNG ĐỐI TƯỢNG SESSION G V : V õ T ấ n D ũ n g 22 LỚP HttpSession G V : V õ T ấ n D ũ n g y Trong Java, Web server cài đặt sẵn đối tượng session thuộc lớp HttpSession. HttpSession dựa vào khái niệm cookie quy định giữa trình khách và trình chủ. Cookie là một mẩu thông tin được gởi về trình duyệt phía máy khách khi có yêu cầu trang từ server. Mỗi khi trình duyệt phát sinh yêu cầu gửi lên server, nó lại chuyển mẩu cookie trở lại trình chủ. Dựa vào cookie, trình khách và trình chủ sẽ có được những thông tin trạng thái thông báo cho nhau. 23 SỬ DỤNG ĐỐI TƯỢNG SESSION VỚI JSP G V : V õ T ấ n D ũ n g y Với đối tượng session thuộc lớp HttpSession, ba phương thức mà ta thường sử dụng nhất là: y public void setAttribute(String name, Object value) throws IlligalStateException y public Object getAttribute(String name) throws IlligalStateException y public void removeAttribute(String name) throws IlligalStateException y Biến session chỉ tồn tại trong một thời gian nhất định. Nếu muốn chủ động làm cho session hết hiệu lực thì ta gọi phương thức: session.invalidate() 24 SỬ DỤNG ĐỐI TƯỢNG SESSION VỚI JSP G V : V õ T ấ n D ũ n g y Chú ý: Giá trị mà ta muốn lưu hay lấy về phải là một đối tượng (Object). Đối với các giá trị có kiểu int, float, boolean,… thì ta phải chuyển sang kiểu lớp tương ứng như Integer, Float, Boolean,… y Ví dụ: Integer tuoicuatui= new Integer(35); session.setAttribute(“tuoi”,tuoicuatui); Integer my_age = (Integer)session.getAttribute(“tuoi”); 25 Viết lại trang Login2.jsp dùng session G V : V õ T ấ n D ũ n g 26 Viết lại trang Login2.jsp dùng session G V : V õ T ấ n D ũ n g 27 SỬ DỤNG ĐỐI TƯỢNG SESSION VỚI Servlet G V : V õ T ấ n D ũ n g y Trong JSP có sẵn đối tượng session để sử dụng nhưng trong Servlet thì session không có sẵn. Ta phải lấy session thông qua đối tượng request. y HttpSession session=request.getSession(); y Nội dung dữ liệu mà ta lưu vào session trong trang JSP hoàn toàn có thể truy xuất được từ servlet. y Nếu ta tạo servlet từ lớp GenericServlet thì ta không có được đối tượng HttpRequest để truy xuất biến session. 28 Sửa lại BookServlet2 thành BookServlet3 G V : V õ T ấ n D ũ n g 29 Sửa lại BookServlet2 thành BookServlet3 G V : V õ T ấ n D ũ n g 30 CÁCH SESSION LÀM VIỆC G V : V õ T ấ n D ũ n g y Khi bộ xử lý Servlet (Servlet engine) của Web server tạo ra đối tượng session, trình chủ gửi một định danh ID của session cho trình duyệt. y Trình duyệt nhận số định danh ID này và xem nó như một mẩu tin cookies. y Bất kỳ khi nào trình duyệt yêu cầu một trang tài liệu nào từ server, trình duyệt sẽ gửi ngược định danh ID này về trình chủ. 31 CÁCH SESSION LÀM VIỆC G V : V õ T ấ n D ũ n g y Thông thường mẩu tin cookies sẽ được trình duyệt hủy bỏ khi bạn đóng cửa sổ trình duyệt. y Trình duyệt còn có thể lưu thông tin cookies lên đĩa cứng cho lần sử dụng kế tiếp. y Bởi vì session chỉ cần tồn tại trong một khoảng thời gian tương tác ngắn nên không nhất thiết lúc nào cũng phải lưu thông tin cookies xuống đĩa cứng trừ khi bạn muốn cấu hình cơ chế lưu cookies này. y Nếu một đối tượng session đã được giải phóng mà trình duyệt vẫn gửi yêu cầu gọi nó thì trình chủ sẽ phát sinh ngoại lệ IllegalStateException. 32 CÁCH SESSION LÀM VIỆC G V : V õ T ấ n D ũ n g 33 BUỘC TRÌNH CHỦ TẠO SESSION MỚI G V : V õ T ấ n D ũ n g y Ví dụ khi người dùng đăng nhập và mua hàng online trên trang web của bạn. Người dùng chọn một số mục hàng rồi sau đó lại không muốn mua. y Thay vì chọn chức năng xóa các mục hàng đã chọn trên trang web thì người dùng lại chọn giải pháp thoát ra và đăng nhập trở lại. Khi đó toàn bộ thông tin mua hàng cùng với các thông tin trước đó phải bị xóa sạch. y Do đó khi người dùng đăng nhập trở lại thì ta phải viết code xóa nội dung trong session hoặc tạo một session mới. 34 BUỘC TRÌNH CHỦ TẠO SESSION MỚI G V : V õ T ấ n D ũ n g y Tạo một session mới hoặc lấy về một đối tượng session hiện có chúng ta đều dùng phương thức getSession(). y Nếu đối số chuyển cho getSession() là true thì session mới sẽ được tạo ra nếu nó chưa có trước đó. Ngược lại với đối số là false, khi không tìm thấy đối tượng session thì phương thức getSession() sẽ trả về giá trị null. y Ví dụ: 35 XỬ LÝ CHẤM DỨT SESSION G V : V õ T ấ n D ũ n g y Đối tượng session có thể chấm dứt và bị hủy bỏ trong hai trường hợp: ta chủ động gọi phương thức invalidate() của nó hoặc Webserver hủy session do thời gian hiệu lực hết hạn (session timeout). y Tùy theo dữ liệu lưu trong session mà ta phải thực hiện một vài thao tác xóa biến, dọn dẹp các đối tượng trước khi session bị hủy. y Ví dụ ta có thể lưu trong các session các thông tin kết nối đến cơ sở dữ liệu. Hãy thực hiện hủy kết nối này trước khi xóa session vì nó làm cho ứng dụng của ta tăng tốc xử lý đối với các người dùng còn lại. 36 XỬ LÝ CHẤM DỨT SESSION G V : V õ T ấ n D ũ n g y Đối tượng session cũng cài đặt cơ chế gọi ngược lại (callback) để thông báo cho một đối tượng nào đó trạng thái đối tượng được ràng buộc vào session hoặc khi session bị hủy. y Cụ thể khi ta gọi session.setAttribute(“somename”,someObject), đối tượng some Object được thông báo rằng nó được ràng buộc vào session. Khi session hết hạn, someObject cũng sẽ được thông báo về sự kết thúc của session để đối tượng có thể tự thực hiện các thao tác hủy của mình. 37 XỬ LÝ CHẤM DỨT SESSION G V : V õ T ấ n D ũ n g y Để cài đặt cơ chế thông báo của session, ta dùng giao diện HttpSessionBindingListener. Giao diện này có 2 phương thức cơ bản là: y public void valueBound(HttpSessionBindingEvent evt) y public void valueUnBound(HttpSessionBindingEvent evt) y valueBound sẽ được gọi khi đối tượng được ràng buộc vào session còn valueUnBound sẽ được gọi khi đối tượng bị loại bỏ khỏi session. y Ví dụ trong slide tiếp sau đây là lớp BindListener lắng nghe các trạng thái ràng buộc đối tượng vào session bằng cách tăng hoặc giảm biến đếm cho biết số lần đối tượng được đưa vào hoặc lấy ra khỏi session. 38 BindListener.java G V : V õ T ấ n D ũ n g 39 BindListener.java G V : V õ T ấ n D ũ n g 40 BindTest.jsp G V : V õ T ấ n D ũ n g 41 BindTest.jsp G V : V õ T ấ n D ũ n g 42 BindTest.jsp G V : V õ T ấ n D ũ n g 43 BindTest.jsp G V : V õ T ấ n D ũ n g 44 XỬ LÝ CHẤM DỨT SESSION G V : V õ T ấ n D ũ n g 45 TẠO SESSION KHÔNG CẦN COOKIES G V : V õ T ấ n D ũ n g y Session mà JSP và Servlet sử dụng dựa trên cơ chế HTTP cookies. Cookies lưu trữ giá trị nhận dạng session ID cho mỗi yêu cầu phát sinh và trao đổi giữa trình duyệt với Web server. y Nhưng rất nhiều người khi lướt web thì họ đã thiết lập cấu hình không cho trình duyệt sử dụng cơ chế cookies. y Ta có thể tự tạo session ID và truyền chúng như là tham số đến tất cả các trang JSP và Servlet trong ứng dụng. y Thay vì để trình duyệt tự động giấu session ID trong cookies và chuyển đi trong mỗi lời yêu cầu, ta thực hiện việc này một cách tường minh với session ID được đặt trên URL. 46 TẠO SESSION KHÔNG CẦN COOKIES G V : V õ T ấ n D ũ n g y Lớp HttpServletResponse cung cấp hai phương thức cho phép chèn session ID vào đường dẫn URL trong các lời gọi trang và Servlet: y public String encodeURL(String url) y public String encodeRedirectURL(String url) y Phương thức encodeURL và encodeRedirectURL sẽ trả về đường dẫn tham chiếu URL chứa session ID. y Trang RewriteDemo.jsp của slide tiếp theo sẽ hiển thị một form, xử lý và nhận dữ liệu do form submit, đặt các giá trị nhận được từ form vào biến session. 47 RewriteDemo.jsp G V : V õ T ấ n D ũ n g 48 RewriteDemo.jsp G V : V õ T ấ n D ũ n g 49 RewriteDemo2.jsp G V : V õ T ấ n D ũ n g 50 TẠO SESSION KHÔNG CẦN COOKIES G V : V õ T ấ n D ũ n g 51 PHẦN 5 SỬ DỤNG ĐỐI TƯỢNG APPLICATION G V : V õ T ấ n D ũ n g 52 LƯU DỮ LIỆU TRONG APPLICATION G V : V õ T ấ n D ũ n g y Lớp HttpSession cung cấp đối tượng session lưu dữ liệu tương ứng và tách biệt đối với người dùng. Mặc dù vậy sẽ có lúc ta cần lưu những biến toàn cục để mọi trang JSP hay Servlet thuộc về các session khác nhau đều có thể nhìn thấy được giá trị của biến. y Trong JSP ta gọi đối tượng application để lưu tất cả các biến có thể nhìn thấy toàn cục. 53 LƯU DỮ LIỆU TRONG APPLICATION G V : V õ T ấ n D ũ n g y Các phương thức mà đối tượng application cung cấp để lưu trữ và loại bỏ biến hoàn toàn tương tự các phương thức mà session cung cấp. 54 LƯU DỮ LIỆU TRONG APPLICATION G V : V õ T ấ n D ũ n g y Ví dụ: trang Default.jsp trong ứng dụng BookStore đếm số người dùng truy cập trang web bằng biến GlobalCounter lưu trong đối tượng application như sau: 55 LƯU DỮ LIỆU TRONG APPLICATION G V : V õ T ấ n D ũ n g y Đối tượng application trong JSP thực sự được cài đặt từ giao diện ServletContext. Trong servlet ta có thể lấy giao tiếp này để dùng cho mục đích lưu biến vào đối tượng application. Biến application trong servlet có được bằng cách sử dụng lệnh sau: y Hoặc trong phương thức init() của Servlet, ta lấy về tham chiếu của đối tượng application như sau: 56 TestVariable.jsp G V : V õ T ấ n D ũ n g y Để phân biệt biến lưu trong session và biến lưu trong application khác nhau ra sao, ta có thể kiểm tra bằng trang TestVariable.jsp như sau: 57 TestVariable.jsp G V : V õ T ấ n D ũ n g 58 TestVariable.jsp G V : V õ T ấ n D ũ n g y Ta gọi trang TestVariable.jsp trong hai cửa sổ trình duyệt khác nhau. Kết quả giá trị biến appCount tăng liên tục trong khi biến sesCounter chỉ tăng cục bộ trong từng cửa sổ trình duyệt. 59 TestVariable.jsp G V : V õ T ấ n D ũ n g 60 HẾT BÀI 7 G V : V õ T ấ n D ũ n g