Luận văn Kiến trúc WEB 2.0

 Crytography (org.apache.shiro.crypto.*): là một sự bổ sung tự nhiên vào một security framefwork. Gói Shiro Crypto bao gồm easy-to-use và các thuật toán crytographi Ciphers, Hashes, Tất cả các lớp trong gói phần mềm này được thiết kế cẩn thận rất dễ sử dụng và dễ hiểu. Bất cứ ai đã sử dụng hỗ trợ mã hóa bản địa của Java biết rằng nó có thể là một con vật đầy thử thách để chế ngự. Shiro crypto API đơn giản hóa cơ chế phức tạp của JAVA và Cryptography dễ dàng để sử dụng cho con người bình thường.

doc124 trang | Chia sẻ: lylyngoc | Lượt xem: 2839 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Luận văn Kiến trúc WEB 2.0, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ưu trữ các thông tin sau: Các "Frame" chứa các trạng thái của các phương thức. Các toán hạng của mã bytecode. Các tham số truyền cho phương thức. Các biến cục bộ. Khi JVM thực thi mã, một thanh ghi cục bộ có tên "Program Counter" được sử dụng. Thanh ghi này trỏ tới lệnh đang thực hiện. Khi cần thiết, có thể thay đổi nội dung thanh ghi để đổi hướng thực thi của chương trình. Trong trường hợp thông thường thì từng lệnh một nối tiếp nhau sẽ được thực thi. Một khái niệm thông dụng khác trong Java là trình biên dịch "Just In Time-JIT". Các trình duyệt thông dụng như Netscape hay IE đều có JIT bên trong để tăng tốc độ thực thi chương trình Java. Mục đích chính của JIT là chuyển tập lệnh bytecode thành mã máy cụ thể cho từng loại CPU. Các lệnh này sẽ được lưu trữ và sử dụng mỗi khi gọi đến. 5.4.2 Quản lý bộ nhớ và dọn rác: Trong C, C++ hay Pascal người lập trình sử dụng phương pháp trực tiếp để cấp phát và thu hồi bộ nhớ ở vùng "Heap". Heap là vùng bộ nhớ lớn được phân chia cho tất cả các luồng. Để quản lý Heap, bộ nhớ được theo dõi qua các danh sách sau: Danh sách các vùng nhớ chưa sử dụng. Danh sách các vùng đã cấp. Khi có một yêu cầu về cấp phát bộ nhớ, hệ thống xem xét trong danh sách chưa cấp phát để lấy ra khối bộ nhớ đầu tiên có kích cỡ sát nhất với lượng bộ nhớ cần thiết . Kỹ thuật cấp phát này giảm tối thiểu việc phân mảnh của heap. "Coalescing" là kỹ thuật khác cũng giảm thiểu việc phân mảnh của heap bằng cách gom lại các vùng nhớ chưa dùng liền nhau thành một khối lớn hơn. Còn kỹ thuật sắp xếp lại các phần đã dùng để tạo vùng nhớ chưa sử dụng lớn hơn gọi là"Compaction". Java sử dụng hai heap riêng biệt cho cấp phát vùng nhớ tĩnh và vùng nhớ động. Một heap (heap tĩnh) chứa các định nghĩa về lớp, các hằng và danh sách các phương thức. Heap còn lại (heap động) được chia làm hai phần được cấp phát theo hai chiều ngược nhau. Một bên chứa đối tượng còn một bên chứa con trỏ trỏ đến đối tượng đó. "Handle" là cấu trúc bao gồm hai con trỏ. Một trỏ đến bảng phương thức của đối tượng, con trỏ thứ hai trỏ đến chính đối tượng đó. Chú ý rằng khi "compaction" cần cập nhật lại giá trị con trỏ của cấu trúc "handle". Thuật toán dọn rác có thể áp dụng cho các đối tượng đặt trong heap động. Khi có yêu cầu về bộ nhớ, trình quản lý heap trước tiên kiểm tra danh sách bộ nhớ chưa cấp phát. Nếu không tìm thấy khối bộ nhớ nào phù hợp (về kích cỡ) thì trình dọn rác sẽ được kích hoạt khi hệ thống rỗi. Nhưng khi đòi hỏi bộ nhớ cấp bách thì trình dọn rác sẽ được kích hoạt ngay. Trình dọn rác gọi phương thức finalize của đối tượng trước khi dọn dẹp đối tượng. Hàm này sẽ dọn dẹp các tài nguyên bên ngoài như các file đang mở. Công việc này không được trình dọn rác thực thi. 5.4.3 Quá trình kiểm tra file .class: Việc kiểm tra được áp dụng cho tất cả các file .class sắp được nạp lên bộ nhớ để đảm bảo tính an toàn. Trình "Class Loader" sẽ kiểm tra tất cả các file .class không thuộc hệ điều hành với mục đích giám sát sự tuân thủ các nghi thức để phát hiện các file .class có nguy cơ gây hư hỏng đến bộ nhớ, hệ thống file cục bộ, mạng hoặc hệ điều hành. Quá trình kiểm tra sẽ xem xét tổng thể tính nguyên vẹn của một lớp. File .class bao gồm ba phần logic là: Bytecode. Thông tin về Class như phương thức, giao diện và các giá trị hằng số được tập hợp trong quá trình biên dịch. Các thuộc tính về lớp. Các thông tin của file .class được xem xét riêng rẽ trong các bảng sau: Bảng Field chứa các thuộc tính. Bảng Method chứa các hàm của class. Bảng Interface và và các hằng số. Quá trình kiểm tra file .class được thực hiện ở bốn mức: Mức đầu tiên thực hiện việc kiểm tra cú pháp để đảm bảo tính cấu trúc và tính toàn vẹn cú pháp của file .class được nạp. Mức thứ hai sẽ xem xét file .class để đảm bảo các file này không vi phạm các nguyên tắc về sự nhất quán ngữ nghĩa. Mức thứ ba sẽ kiểm tra bytecode. Trong bước này sẽ kiểm tra số thông số truyền vào phương thức, khả năng truy xuất sai chỉ số của mảng, chuỗi, biểu thức. Mức thứ tư sẽ kiểm tra trong thời gian thực thi để giám sát các việc còn lại mà ba bước trên chưa làm. Ví dụ như liên kết tới các lớp khác trong khi thực thi, hay kiểm tra quyền truy xuất. Nếu mọi điều thỏa mãn, lớp sẽ được khởi tạo. 5.5 Bộ công cụ phát triển JDK (Java Development Kit) Sun Microsystem đưa ra ngôn ngữ lập trình Java qua sản phẩm có tên là Java Development Kit (JDK). Ba phiên bản chính là: Java 1.0 - Sử dụng lần đầu vào năm 1995. Java 1.1 – Ðưa ra năm 1997 vớI nhiều ưu điểm hơn phiên bản trước. Java 2 – Phiên bản mới nhất. JDK bao gồm Java Plug-In, chúng cho phép chạy trực tiếp Java Applet hay JavaBean bằng cách dùng JRE thay cho sử dụng môi trường thực thi mặ c định của trình duyệt. JDK chứa các công cụ sau: 5.5.1 Trình biên dịch, ’javac’ Cú pháp: javac [options] sourcecodename.java 5.5.2 Trình thông dịch, ’java’ Cú pháp: java [options] classname 5.5.3 Trình dịch ngược, ’javap’ javap dịch ngược bytecode và in ra thông tin về các thuộc tính (các trường), các phương thức của một lớp. Cú pháp: javap [options] classname 5.5.4 Công cụ sinh tài liệu, ’javadoc’ Tiện ích này cho phép ta tạo ra tệp HTML dựa trên các lời giải thích trong mã chương trình (phần nằm trong cặp dấu /*.... */). Cú pháp: javadoc [options] sourcecodename.java 5.5.5 Chương trình tìm lỗi – Debug, ’jdb’ Cú pháp: jdb [options] sourcecodename.java Hay jdb -host -password [options] sourcecodename.java 5.5.6 Chương trình xem Applet, ’appletviewer’ Cú pháp: appletviewer [options] url 5.6 Java Core API: Nhân Java API được thay thế bởi phiên bản JFC 1.1. Một số package thông dụng được: 5.6.1 java.lang: Chứa các lớp quan trọng nhất của ngôn ngữ Java. Chúng bao gồm các kiểu dữ liệu cơ bản như ký tự, số nguyên,… Chúng cũng chứa các lớp làm nhiệm vụ xử lý lỗi và các lớp vào ra chuẩn. Một vài lớp quan trọng khác như String hay StringBuffer. 5.6.2 java.applet: Đây là package nhỏ nhất chứa một mình lớp Applet. Các Applet nhúng trong trang Web hay chạy trong appletviewer đều thừa kế từ lớp này. 5.6.3 java.awt: Package này đươợc gọi là Abstract Window Toolkit (AWT). Chúng chứa các lớp dùng để tạo giao diện đồ họa. Một số lớp bên trong là: Button, GridBagLayout, Graphics. 5.6.4 java.io: Cung cấp thư viện vào ra chuẩ. Chúng cho phép tạo và quản lý dòng dữ liệu theo nhiều cách. 5.6.5 java.util: Package này cung cấp một số công cụ hữu ích. Một vài lớp của package này là: Date, Hashtable, Stack, Vector và StringTokenizer. 5.6.6 java.net: Cung cấp khả năng giao tiếp với máy từ xa. Cho phép tạo và kết nối tới Socket hoặc URL. 5.6.7 java.awt.event: Chứa các lớp, giao diện dùng để xử lý các sự kiện trong chương trình như chuột, bàn phím. 5.6.8 java.rmi: Công cụ để gọi hàm từ xa. Chúng cho phép tạo đối tượng trên máy khác và sử dụng các đối tượng đó trên máy cục bộ. 5.6.9: java.security: Cung cấp các công cụ cần thiết để mã hóa và đảm bảo tính an toàn của dữ liệu truyền giữa máy trạm và máy chủ. 5.6.10 java.sql: Package này chứa Java DataBase Connectivity (JDBC), dùng để truy xuất cơ sở dữ liệu quan hệ như Oracle, SQL Server,.... 5.7 Các đặc trưng mới của Java 2: Các phiên bản trước của Java chỉ thích hợp để viết các ứng dụng nhỏ trên Web hơn là xây dựng các ứng dụng chạy trên mạng để đảm nhiệm toàn bộ các công việc của của một công ty hoặc hệ thống phân tán. Java 2 đáp ứng yêu cầu này. Một vài đặc trưng của chúng là: 5.7.1 Swing: Đây là một tập các lớp và giao diện mới dùng để tạo giao diện ứng dụng đồ họa "Look and Feel". 5.7.2 Kéo và thả: Đây là khả năng di chuyển thông tin giữa các ứng dụng hay các phần khác nhau của chương trình. 5.7.3 Java 2D API: Chứa tập hợp các lớp hỗ trợ cho ảnh và đồ họa hai chiều. 5.7.4 Java sound: Tập hợp hoàn toàn mới các lớp đặc trưng về âm thanh của Java. 5.7.5 RMI: RMI (Remote Method Invocation) cho phép các ứng dụng gọi các phương thức của đối tượng tại máy khác và cho phép giao tiếp với chúng. Chương 6: Nghiên cứu MySQL 6.1 Giới thiệu MySQL: CSDL là 1 phần quan trọng không thể thể thiếu được trong các ứng dụng web chuyên nghiệp. MySQL từ lâu đã là hệ CSDL được dùng phổ biến nhất với PHP vì tính gọn nhẹ, nhanh, miễn phí và được PHP hỗ trợ sẵn. Trong bài viết này chúng ta sẽ tìm hiểu cách kết nối vào CSDL MySQL, truy cập và lưu trữ dữ liệu với PHP. 6.2 Kết nối vào MySQL Server: PHP cung cấp hàm mysql_connect để kết nối vèo MySQL server. Cú pháp của hàm này như sau: mysql_connect($server_address, $username, $password) $server_address là địa chỉ của MySQL server, có thể là domain name hoặc IP address. $username là tên account dùng để login vào MySQL server, ta sẽ sử dụng giá trị "root" cho $username. $password là mật mã để kết nối vào MySQL server, các ví dụ trong bài viết sẽ sử dụng chuỗi rỗng "" làm mật mã. Hàm mysql_connect sẽ trả về 1 kết nối đến MySQL server nếu như quá trình kết nối thành công, hoặc trả về giá trị FALSE nếu như kết nối không được. Để đóng kết nối tới MySQL server, PHP cung cấp hàm mysql_close. Đoạn mã sau ví dụ quá trình kết nối vào MySQL server và đóng kết nối. 6.3 Chọn CSDL để làm việc: Sau khi connet vào MySQL server, thao tác tiếp theo là chọn CSDL để làm việc. PHP cung cấp cho ta hàm mysql_select_db để làm việc này. Cú pháp của hàm này như sau: mysql_select_db($db_name[, $conn])Với $db_name là tên CSDL cần chọn, $conn là kết nối được thực hiện qua lệnh mysql_connect. Các ví dụ trong bài viết này sẽ sử dụng CSDL có tên là test: 6.4 Thực thi một câu lệnh Select và lấy kết quả trả về: PHP cung cấp cho ta 3 hàm hữu dụng để thực hiện công việc này: $result = mysql_query($sql, $conn): thực hiện câu lệnh SQL được cung cấp qua tham số $sql và trả về 1 kết quả kiểu $result (hàm này trả về FALSE nếu như câu lệnh thực hiện không thành công). mysql_num_rows($result): hàm này trả về số lượng row lấy được qua câu lệnh SELECT (được thực thi bởi hàm mysql_query) trước đó. $row = mysql_fetch_row($result), $row = mysql_fetch_assoc($result): trả về dòng kết quả hiện thời của câu lệnh select và chuyển con trỏ tới dòng tiếp theo (như vậy lệnh gọi mysql_fetch_row hoặc mysql_fetch_assoc tiếp đó sẽ trả về dòng tiếp theo); hoặc giá trị FALSE nếu như không còn dòng nào để trả về nữa. Kết quả trả về từ 2 hàm này là 1 array. mysql_error($conn): trả về thông báo lỗi của MySQL server nếu như một lệnh trước đó có lỗi. Để hiểu rõ hơn công dụng của các hàm trên, đồng thời phân biệt sự khác nhau giữa 2 hàm mysql_fetch_row và mysql_fetch_assoc, ta cung xem xét các ví dụ sau. Các ví dụ của ta sẽ sử dụng table có tên là member với các trường và dữ liệu như sau: username password abc 123 def 456 Ví dụ 1: dùng mysql_fetch_row() \n"; while ( $row = mysql_fetch_row($result) ) { echo "Username = ".$row[0]."\n"; echo "Password = ".$row[1]."\n"; } //end while //nên luôn giải phóng bộ nhớ sau khi lấy hết các row trả về từ câu lệnh SELECT mysql_free_result($result); //đóng kết nối mysql_close($conn); ?> Hàm mysql_fetch_row() sẽ trả về 1 array mà phần tử thứ [0] sẽ tương ứng với cột đầu tiên của table, phần tử thứ [1] sẽ tương ứng với cột thứ hai của table...Chương trình trên sẽ in ra ra 4 dòng: Username = abc Password = 123 Username = def Password = 456 Ví dụ 2: dùng mysql_fetch_assoc() \n"; while ( $row = mysql_fetch_assoc($result) ) { echo "Username = ".$row['username']."\n"; echo "Password = ".$row['password']."\n"; } //end while //nên luôn giải phóng bộ nhớ sau khi lấy hết các row trả về từ câu lệnh SELECT mysql_free_result($result); //đóng kết nối mysql_close($conn); ?> Hàm mysql_fetch_assoc() sẽ trả về 1 array mà các phần tử sẽ được truy cập qua tên, với tên được lấy từ tên các cột của table. Chương trình ví dụ 2 cũng sẽ in ra ra 4 dòng: Username = abc Password = 123 Username = def Password = 456 6.5 Thực thi một câu lệnh Update, Insert hoặc Delete: Hàm mysql_query cũng được dùng để thực thi các câu lệnh DELETE, INSERT hoặc UPDATE, nhưng lúc này hàm sẽ trả về TRUE nếu câu lệnh thực hiện thành công và FALSE trong trường hợp ngược lại. Để lấy số lượng các row được chèn với lệnh INSERT hoặc bị thay đổi bởi lệnh UPDATE, PHP cung cấp cho ta hàm mysql_affected_rows. Ta hãy xem ví dụ sau: \n"; //ta chỉ chèn 1 dòng nên hàm mysql_affected_rows sẽ trả về 1 $sql = "UPDATE member SET password='111' WHERE username='xyz'"; $result = mysql_query($sql, $conn); //đổi password của accoutn xyz if ( !$result ) die("Không thể thực hiện được câu lệnh SQL: ".mysql_error($conn)); echo "Số lượng row được thay đổi: ".mysql_affected_rows($conn)."\n"; //ta thay đổi 1 dòng nên hàm mysql_affected_rows sẽ trả về 1 $sql = "DELETE FROM member"; $result = mysql_query($sql, $conn); //xoá hết tất cả các account if ( !$result ) die("Không thể thực hiện được câu lệnh SQL: ".mysql_error($conn)); echo "Số lượng row được xoá: ".mysql_affected_rows($conn)."\n"; //ta xoá tất cả 3 dòng nên hàm mysql_affected_rows sẽ trả về 3 //đóng kết nối mysql_close($conn); ?> 6.6 Lưu ý vấn đề bảo mật với lỗi SQL Injection: Nếu bạn cần cung cấp 1 tham số cho câu lệnh SQL, nhất là các tham số từ trình duyệt do người dùng nhập vào, bạn hãy lưu ý đề phòng lỗi bảo mật SQL Injection. Giả sử bạn muốn thay đổi mật mã của account xyz, mật mã mới được người dùng nhập vào và lưu vào trong biến $newPwd, đoạn mã đổi password có thể tương tự như sau: Giả sử người dùng nhập vào mật mã mới là zzz, câu lệnh SQL sẽ trở thành UPDATE member SET password='zzz' WHERE username='xyz' Hoàn toàn hợp lệ và đúng đắn, không có gì phải thắc mắc hết. Nhưng giả sử người dùng nhập vào mật mã mới là zzz'#, câu lệnh SQL sẽ trở thành UPDATE member SET password='zzz'#' WHERE username='xyz' Nhưng gì phía sau ký tự # sẽ được MySQL xem là chú thích và sẽ bỏ qua, như vậy câu lệnh SQL của chúng ta trên thực tế sẽ tương đương với: UPDATE member SET password='zzz' Vậy là xong! Sau khi chạy câu lệnh này, password của tất cả các account đều là zzz hết, tất hiên là account admin cũng sẽ bị đổi password thành zzz và lúc này hậu quả tiếp theo ra sao chắc bạn cũng đã rõ! Để tránh bị SQL injection, khi đưa các tham số vào câu lệnh SQL, bạn nên luôn nhớ và áp dụng 2 điều sau: Nếu tham số là số (số nguyên hoặc số thực), cộng thêm 0 vào tham số trước khi đưa vào câu lệnh SQL. Tức là: $thamso+=0; $sql = "...$thamso..."; Nếu tham số là chuỗi, sử dụng hàm mysql_real_escape_string trước khi đưa tham số vào câu lệnh SQL. Tức là: $thamso = mysql_real_escape_string($thamso, $conn); $sql = "...'$thamso'..."; Chương 7: Nghiên cứu LDAP. Hiện nay, để xây dựng các hệ thống lớn, điều tối quan trọng là phải làm cách nào để có thể tích hợp dữ liệu để từ đó có thể dùng chung giữa các hệ thống khác nhau. Trong đó, tích hợp tài khoản của người sử dụng là vấn đề cần thiết nhất trong những cái "tối quan trọng" trên. Hãy tưởng tượng một hệ thống với khoảng 5 - 6 mô đun khác nhau, mỗi mô đun lại được thiết kế trên một nền tảng khác nhau (Có ông thì dùng Oracle + AS Portal, có người thì xài DB2 với WebSphere, lão khác thì MySQL với phpnuke, ông thì xài Wíndow, lão thì cài Linux, có thằng điên lại chỉ thích Unix...hic, cuộc đời thật đúng là bể khổ), do đó cần có một hệ thống người dùng khác nhau. Vậy thì với mỗi mô đun, người sử dụng cần phải có một User Name, một mật khẩu khác nhau, đó là điều không thể chấp nhận được. Người dùng chẳng mấy chốc mà chán ghét hệ thống. Làm cách nào để có thể tích hợp được người dùng giữa các hệ thống trên? Câu trả lời đó là LDAP. Vây LDAP là gì? LDAP - viết tắt của Lightweight Directory Access Protocol, hay dịch ra tiếng Việt có nghĩa là giao thức truy cập nhanh các dịch vụ thư mục.  Là một giao thức tìm, truy nhập các thông tin dạng thư mục trên server.  Nó là giao thức dạng Client/Server dùng để truy cập dịch vụ thư mục. LDAP chạy trên TCP/IP hoặc các dịch vụ hướng kết nối khác.  Là một mô hình thông tin cho phép xác định cấu trúc và đặc điểm của thông tin trong thư mục. Là một không gian tên cho phép xác định cách các thông tin được tham chiếu và tổ chức. Một mô hình các thao tác cho phép xác định các tham chiếu và phân bố dữ liệu. Là một giao thức mở rộng Là một mô hình thông tin mở rộng. Ở đây chúng ta cần tránh hiểu nhầm từ "thư mục" như trên Windows là folder hay directory, đó là thư mục theo nghĩa hẹp để quản lý hệ thống tệp tin. Từ thư mục trong LDAP mang ý nghĩa rộng hơn, nó bao hàm các cấu trúc dữ liệu dạng liệt kê theo thư mục (hay mục lục) - một "từ khoá" của dân thư viện nhằm ám chỉ cách thức sắp xếp dữ liệu để tiện truy xuất nhất.  Làm việc với LDAP thông qua PHP Trình tự cơ bản khi có thao tác với LDAP gồm các bước: Connect (kết nối với LDAP). Bind (kiểu kết nối: nặc danh hoặc đăng nhập xác thực). Search (tìm kiếm). Interpret search (xử lý tìm kiếm). Result (kết quả). Close connection (đóng kết nối). Ldap_connect():  Hàm kết nối tới máy chủ LDAP, hàm này có 2 tham số: hostname (tên máy chủ LDAP) và port (cổng kết nối, mặc định là cổng 389) Ldap_connect(string hostname, int port); Code: Ldap_bind();  Hàm nối kết với server LDAP để có thể thao tác với LDAP Vd kết nối với LDAP server bằng user và password hợp lệ Nếu kết nối bằng quyền anonymously Code: ldap_search(); ldap_search ( resource link_identifier, string base_dn, string filter [, array attributes [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]] ) VD tìm kiếm các thông tin của tất cả mọi người ở trong “My Company” nơi surname hoặc given name chứa trong biến $person. Ví dụ này yêu cầu server tìm ra thông tin của nhiều hơn một thuộc tính cần tìm kiếm. Code: Ldap_close(); Hàm đóng kết nối với LDAP, hàm này tương đương với ldap_unbind(); bool ldap_unbind ( resource link_identifier ); Nếu kết nối đóng thành công sẽ trả về giá trị TRUE, ngược lại là FALSE. ldap_add(); Hàm thêm các entry vào thư mục LDAP: bool ldap_add ( resource link_identifier, string dn, array entry ). Code: ldap_delete(); Xóa một entry khỏi thư mục LDAP Code: bool ldap_delete ( resource link_identifier, string dn ) Hàm trả về giá trị TRUE nếu xóa thành công và FALSE nếu thất bại: ldap_compare(); So sánh giá trị của một thuộc tính: mixed ldap_compare ( resource link_identifier, string dn, string attribute, string value ) VD: Code: Ldap_count_entries(); Đếm số lượng các entry được tìm thấy từ kết quả của lệnh tìm kiếm: int ldap_count_entries ( resource link_identifier, resource result_identifier ) ldap_error(); Trả lại thông báo lỗi LDAP của lệnh LDAP cuối cùng: string ldap_error ( resource link_identifier ) ldap_first_attribute(); Hàm trả lại thuộc tính đầu tiên của entry: string ldap_first_attribute ( resource link_identifier, resource result_entry_identifier,  int &ber_identifier ) ldap_first_entry(); Trả lại kết quả id đầu tiên của entry: ldap_first_entry ( resource link_identifier, resource result_identifier ) ldap_first_reference(); Trả lại tham chiếu đầu tiên: ldap_first_reference ( resource link, resource result ) ldap_free_result(); Giải phóng kết quả bộ nhớ: bool ldap_free_result ( resource result_identifier ) Chương 8: Nghiên cứu Spring MVC. 8.1 Giới thiệu về Spring: Spring là một application framework mã nguồn mở, được giới thiệu vào năm 2002. Rod Johnson đã đưa ra ý tưởng này từ kinh nghiệm làm việc với kiến trúc J2EE. Mục đích của Spring là trở thành một application framework. Các framework phổ biến khác như Struts, Tapestry, JSF,... là các framework tốt cho tầng web nhưng khi chúng ta sử dụng các framework này, chúng ta phải cung cấp thêm framework khác để giải quyết tầng enterprise mà tích hợp tốt với các framework này. Spring làm giảm bớt vấn đề này bằng cách cung cấp một framework toàn diện bao gồm: Core bean container. MVC framework. AOP integration framework. JDBC integration framework. EJB integration framework. Nó cũng cung cấp module tích hợp với O/R tool như Hibernate và JDO. Do đó Spring framework có thể được xem như một kiến trúc chứa 7 module. Chức năng của mỗi thành phần như sau: 8.1.1 Core Container: Core container cung cấp chức năng cơ bản của Spring. Thành phần chính của nó là Bean Factory, một cài đặt của Factory pattern. BeanFactory áp dụng IoC pattern để đặc tả sự phụ thuộc từ code của ứng dụng. 8.1.2 Spring Context/Application Context: Spring context là một file cấu hình để cung cấp thông tin ngữ cảnh của Spring. Spring context cung cấp các service như JNDI access, EJB integration, e-mail, internalization, validation, và scheduling functionality. 8.1.3 Spring AOP (Aspect-Oriented): Spring AOP module tích hợp chức năng lập trình hướng khía cạnh vào Spring framework thông qua cấu hình của nó. Spring AOP module cung cấp các dịch vụ quản lý giao dịch cho các đối tượng trong bất kỳ ứng dụng nào sử dụng Spring. Với Spring AOP chúng ta có thể tích hợp declarative transaction management vào trong ứng dụng mà không cần dựa vào EJB component. Spring AOP module cũng đưa lập trình metadata vào trong Spring. Sử dụng cái này chúng ta có thể thêm annotation vào source code để hướng dẫn Spring nơi và làm thế nào để liên hệ với aspect. 8.3.4 Spring DAO: Tầng JDBC và DAO đưa ra một cây phân cấp exception để quản lý kết nối đến database, điều khiển exception và thông báo lỗi được ném bởi vendor của database. Tầng exception đơn giản điều khiển lỗi và giảm khối lượng code mà chúng ta cần viết như mở và đóng kết nối. Module này cũng cung cấp các dịch vụ quản lý giao dịch cho các đối tượng trong ứng dụng Spring. 8.1.5 Spring ORM: Spring có thể tích hợp với một vài ORM framework để cung cấp Object Relation tool bao gồm: JDO, Hibernate, OJB và iBatis SQL Maps. 8.1.6 Spring Web module: Nằm trên application context module, cung cấp context cho các ứng dụng web. Spring cũng hỗ trợ tích hợp với Struts, JSF và Webwork. Web module cũng làm giảm bớt các công việc điều khiển nhiều request và gắn các tham số của request vào các đối tượng domain. 8.1.7 Spring MVC Framework: MVC Framework thì cài đặt đầy đủ đặc tính của MVC pattern để xây dựng các ứng dụng Web. MVC framework thì cấu hình thông qua giao diện và chứa được một số kỹ thuật view bao gồm: JSP, Velocity, Tiles và generation of PDF và Excel file. Ví dụ:  Có một số kỹ thuật tuyệt vời cho tầng web như: Spring MVC framework, Struts, JSF, WebWork, JSP, Tapestry, FreeMarker,...Developer sẽ bị lúng túng đối chiếu những điểm mạnh và xấu của tất cả chúng. Mỗi khi họ chọn một kỹ thuật và bắt đầu cài đặt, thì sau đó nếu họ muốn thay đổi một kỹ thuật khác thì rất khó. Nhưng Spring đưa ra các module cho tất cả các kỹ thuật trên, và rất đơn giản để thay đổi file cấu hình. Với phương pháp này, nó có khả năng cho cả team thử và test các tất cả các hình thức trên và xem ảnh hưởng cùng tốc độ trước khi quyết định chọn lựa.  JSP là một view template mặc định. "InternalResouceViewResolver" có thể được sử dụng cho mục đích này. 8.2 Các khái niệm chính của Spring: Các khái niệm chính của Spring là: IoC và Aspect Orient Programming. Spring dựa vào Depenecy injection của IoC. Chúng ta không trực tiếp kết nối các component và service lại với nhau trong code mà thông qua file cấu hình. Một container thì chịu trách nhiệm móc nối nó. Khái niệm này thì tương tự với Declarative Management.  8.2.1 Dependency Injection: Depedency injection là một pattern chịu trách nhiệm tạo đối tượng và các liên kết giữa các đối tượng bị loại bỏ ra khỏi các đối tượng và chuyển đến cho factory quản lý. Các đối tượng của ứng dụng không chịu trách nhiệm tìm kiếm các resource mà chúng phụ thuộc. Và vì thế nên sự phụ thuộc được đảo ngược vào trong các đối tượng.  Theo phương pháp này, các đối tượng có thể được rút trích thông qua Setter Injection (các thuộc tính của Java-Beans) hoặc Constructor Injection (tham số của constructor). Mỗi phương thức có thuận lợi và bất lợi riêng. Bình thường trong Java bean, chúng ta sử dụng phương thức setter và getter để thiết lập và lấy giá trị của thuộc tính như sau: public class namebean { String name; public void setName(String a) name = a; } public String getName() { return name; } } Chúng ta sẽ tạo một thể hiện của bean "namebean" (gọi là bean1) và thiết lập thuộc tính: bean1.setName("Tom"). Còn trong setter injection, chúng ta thiết lập thuộc tính "name" trong subelement của thẻ trong file cấu hình Spring như sau: Tom Subelement thiết lập thuộc tính "name" bằng cách gọi phương thức set như sau: setName("Tom"); => tiến trình này được gọi là setter injection. Ví dụ về constructor injection, chúng ta sử dụng constructor với một tham số: public class namebean { String name; public namebean(String a) { name = a; }  }  Chúng ta sẽ thiết lập thuộc tính "name" trong khi tạo thể hiện của bean "namebean" như sau: namebean bean1 = new namebean("Tom");  Ở đây chúng ta sử dụng element để thiết lập thuộc tính sử dụng constructor injection như sau: My Bean Value   Để thiết lập các thuộc tính tham chiếu đến bean khác - , subelement được sử dụng như sau: 8.2.2 Aspect-oriented Programming: Kỹ thuật lập trình đưa ra cách phân chia các yêu cầu của hệ thống. Hệ thống được phân ra thành một vài component đảm trách một chức năng xác định. Bên cạnh các chức năng cơ bản thì các dịch vụ (yêu cầu hệ thống) như logging, transaction management, security...phải có trong chương trình. Các dịch vụ hệ thống này được gọi là 'cross-cutting concern' - nghĩa là chúng cắt chéo qua nhiều component trong hệ thống. AOP có khả năng module hóa các service này và sau đó cung cấp đến các component và chúng ta có thể tập trung vào yêu cầu chính (core concern). Trong Spring, lát cắt (aspect) được cắm vào trong các đối tượng của XML file như các JavaBean. Tiến trình này gọi là sự đan xen (weaving). Container là khái niệm chính của Spring. Để quản lý vòng đời và cấu hình các đối tượng của ứng dụng. Chúng ta có thể cấu hình mỗi bean nên được tạo như thế nào hoặc làm thế nào để tạo một instance của bean hoặc làm thế nào kết hợp chúng lại. Spring không sử dụng các EJB container hạnh nặng. Spring có 2 container phân biệt: Bean Factory được định nghĩa bởi org.springframework. beans.factory.BeanFactory là một container đơn giản nhất, cung cấp hỗ trợ dependency injection. Application context được định nghĩa bởi org.springframework.context.ApplicationContext, cung cấp các service của application framework. 8.2.2.1 Bean Factory: Bean factory thì cài đặt factory design pattern và chức năng của nó là tạo và phân phát các bean. Bean factory biết về nhiều đối tượng trong ứng dụng, nó có thể tạo mối kết hợp cho các đối tượng khi chúng được khởi tạo. Điều này sẽ giảm bớt gánh nặng cho bean và client. Có một vài cài đặt của BeanFactory. Một cái hữu ích nhất là org.springframework.beans.factory.xml.XmlBeanFacto ry. Nó sẽ load các bean dựa vào định nghĩa trong XML file. Để tạo một thể hiện của XmlBeanFactory, hãy chuyển vào constuctor của nó một InputStream. Resource này sẽ cung cấp XML cho factory. BeanFactory factory = new XmlBeanFactory(new FileInputStream("myBean.xml"));  => dòng này bảo bean factory đọc định nghĩa bean từ XML file. Định nghĩa bean bao gồm mô tả bean và các thuộc tính của nó. Nhưng bean factory vẫn chưa khởi tạo nó. Để rút trích một bean từ BeanFactory, hãy gọi phương thức getBean(). Khi phương thức getBean() được gọi, factory sẽ khởi tạo bean và bắt đầu thiết lập các thuộc tính của nó sử dụng depedency injection. myBena bean1 = (myBean)factory.getBean("myBean"); 8.2.2.2 Application Context: Trong khi Bean Factory được sử dụng cho các ứng dụng đơn giản, thì Application Context là một container nâng cao của Spring. Giống như BeanFactory, nó có thể được sử dụng để load các định nghĩa bean, gắn các bean với nhau và phân phát các bean theo yêu cầu. Nó cũng cung cấp: Giải quyết text message, bao gồm hỗ trợ internationlization. Cách chung để load file resource. Các sự kiện để bean được đăng ký như các trình lắng nghe. Có 3 cách sử dụng cài đặt Application Context: ClassPathXmlApplicationContext: Nó load định nghĩa context từ XML file được đặt trong classpath, xem các định nghĩa context như các tài nguyên của classpath. Application context thì được load từ classpath của ứng dụng như sau: ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); FileSystemXmlApplicationContext: Nó load định nghĩa context từ XML file trong từ hệ thống file. Application Context được load từ hệ thống file như sau: ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml"); XmlWebApplicationContext: Nó sẽ load các định nghĩa context từ XML file trong ứng dụng web.  Spring thì nhẹ về cả kích cỡ và chi phí. Toàn bộ framework có thể được phân phát trong JAR file chỉ hơn 1.7MB. Chi phí được yêu cầu bởi Spring thì không đáng kể. Và Spring không ràng buộc, ví dụ: các đối tượng trong ứng dụng Spring không phụ thuộc vào các class của Spring. 8.3 Relase info: Spring framework được download ở trang  Trên đó có 2 file zip: một file có dependencies, một file thì không. Spring framework với dependencies thì lớn hơn và chứa tất cả thư viện phụ thuộc.  Nội dung của phân phối "-with-dependencies" (~60 MB): "dist" chứa các file jar của bảng phân phối và một file nén chứa tất cả source code. "docs" chứa tài liệu có định dạnh PDF, HTML và javadocs. "lib" chứa tất cả thư viện cần để xây dựng framework hoặc chạy các ví dụ. "src" chứa các file Java source của framework. "mock" chứa các file Java source cho mock và test. "test" chứa file java cho bộ test của Spring. "tiger/src" chứa các file JDK-1.5-specific Java source cho framework. "tiger/test" chứa các file JDK-1.5-specific Java source cho bộ test của Spring. "aspectj/src" chứa tất cả file AspectJ-specific source cho framework "aspectj/test" chứa tất cả file AspectJ-specific source cho cho bộ test của Spring. "samples" chứa các ứng dụng demo và chương trình giới thiệu. 8.4 Spring Application: Các bước tạo ứng dụng sử dụng Spring: Một interface định nghĩa các chức năng. Một implementation chứa các thuộc tính, các phương thức settter và getter. Một file XML gọi là file cấu hình Spring. Chương trình client sử dụng chức năng trên. 1. public interface Hello { public String sayHello(String s); } 2.  public class HelloImpl implements Hello{ private String greeting; /** * Class constructor * @param s */ public HelloImpl(){ } public HelloImpl(String s){ greeting = s; } /** * function */ public String sayHello(String s) { return greeting + s; } /** * @return Returns the greeting. */ public String getGreeting() { return greeting; } /** * @param greeting The greeting to set. */ public void setGreeting(String greeting) { this.greeting = greeting; } } 3. Good Morning! 4. import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFacto ry; import org.springframework.core.io.ClassPathResource; public class HelloClient { /** * @param args */ public static void main(String[] args) { try { ClassPathResource resource = new ClassPathResource("hello.xml"); BeanFactory factory = new XmlBeanFactory(resource); HelloImpl bean = (HelloImpl) factory.getBean("hello"); String hello = bean.sayHello("You"); System.out.println(hello); } catch (Exception e) { e.printStackTrace(); } } } Chạy ứng dụng sẽ kết xuất như sau: 2007/01/12 13:43:16 org.springframework.core.CollectionFactory 情報: JDK 1.4+ collections available 2007/01/12 13:43:17 org.springframework.beans.factory.xml.XmlBeanDefin itionReader loadBeanDefinitions 情報: Loading XML bean definitions from class path resource [hello.xml] Good Morning!You Ở đây, HelloImpl cài đặt giao tiếp Hello. Mặc dù không cần thiết phải dấu cài đặt phía sau một giao tiếp. HelloImpl có một thuộc tính greeting. Thuộc tính này có thể được thiết lập theo 2 cách: bằng phương thức setter hoặc bằng constructor. File hello.xml khai báo một thể hiện của HelloImpl trong container của Spring và cấu hình giá trị của thuộc tính greeting là "Good Morning!". Root của file hello.xml là element - là root element của bất kỳ file cấu hình nào của Spring. Element được sử dụng để bảo Spring container về lớp và nó nên được cấu hình như thế nào. Ở đây, thuộc tính id là tên của interface và thuộc tính class xác định tên lớp đầy đủ của bean. Trong bean, element được sử dụng để thiết lập thuộc tính, trong trường hợp này là thuộc tính greeting. Sử dụng , chúng ta nói với Spring container gọi phương thức setGreeting(). Giá trị của greeting được định nghĩa trong element . Container sẽ khởi tạo HelloImpl dựa vào định nghĩa XML như sau: HelloImpl hello = new HelloImpl (); hello.setGreeting("Good Morning!...");  Tương tự, thuộc tính greeting có thể được thiết lập thông qua constructor có 1 tham số của  HelloImpl như sau: Good Morning!...   Bây giờ thì container khởi tạo HelloImpl dựa vào định nghĩa XML như sau: HelloImpl hello = new HelloImpl("Good Morning..."); Ở chương trình client, lớp BeanFactory được sử dụng là Spring container. Sau đó phương thức getBean() được gọi để lấy tham chiếu đến bean "hello". Với tham chiếu này thì phương thức sayHello() được gọi. Bước kế tiếp chúng ta sẽ xem làm thế nào để chạy chương trình này như một servlet. Đầu tiên copy spring.jar đến thư mục common\lib của Tomcat và khởi động tomcat server. Sau khi thiết lập classpath, tạo file HelloServlet.java như sau: HelloServlet.java import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFacto ry; import org.springframework.core.io.ClassPathResource; public class HelloServlet extends HttpServlet{ /** *  */ private static final long serialVersionUID = 1L; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("userName"); response.setContentType("text/html"); ClassPathResource resource = new ClassPathResource("hello.xml"); BeanFactory factory = new XmlBeanFactory(resource); Hello bean = (Hello) factory.getBean("hello"); PrintWriter out = response.getWriter(); out.write(bean.sayHello(name)); } } index.html web.xml springservlet hello HelloServlet 1 hello /hello index.html Bây giờ chúng ta sẽ vào tiến trình chính của bất kỳ ứng dụng enterprise nào: data persistence. Spring có framework data access riêng của nó. Spring chia phần cố định và tùy biến của tiến trình data access thành hai lớp phân biệt: Template và Callback. Template quản lý phần cố định của framework như data connection, quản lý tài nguyên, điều khiển giao dịch...Trong khi Callback định nghĩa các thứ được xác định trong ứng dụng như tạo statement, móc nối tham số...Lớp Template của Spring là JdbcTemplate. Một data source phải được cung cấp bên trong JdbcTemplate. Một ví dụ về kết nối CSDL sử dụng JdbcTemplate như sau. Ở đây chúng ta sử dụng CSDL MySQL. Sau khi tạo bảng user(name text, place text) trong CSDL test, chúng ta tạo chương trình như sau: 8.4.1 Tạo interface DataConnection chứa hàm lấy về một dataSource để cung cấp cho JdbcTemplate: import javax.sql.DataSource; public interface DataConnection { public DataSource getDataSource(); } 8.4.2 Tạo cài đặt của interface đó chứa thuộc tính dataSource và các phương thức setter, getter: import javax.sql.DataSource; public class DataConnectionImpl implements DataConnection{ private DataSource dataSource; public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } } 8.4.3 Tạo DataConServlet thực hiện nghiệp vụ là insert dữ liệu: import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFacto ry; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; public class DataConServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String place = request.getParameter("place"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); ClassPathResource resource = new ClassPathResource("applicationContext.xml"); BeanFactory factory = new XmlBeanFactory(resource); DataConnection bean = (DataConnection) factory.getBean("dataConnection"); DataSource ds = bean.getDataSource(); try { JdbcTemplate template = new JdbcTemplate(ds); String sql = "insert into user values ('" + name + "','" + place+ "')"; template.execute(sql); out.write("A record is added!"); } catch (Exception e) { e.printStackTrace(); } } } 8.4.4 Tạo client sử dụng servlet trên: Name: Place: 8.4.5. Cấu hình bean “dataSource”: Good Morning! com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/test root root 8.4.6. Cấu hình servlet: <web-app id="WebApp_ID" version="2.4" xmlns="" xmlns:xsi=""xsi:schemaLocation=" "> springservlet data DataConServlet data /data index.html Để mapping các resource của Hibernate, cần tạo một thể hiện của SessionFactory, LocalSessionFactoryBean thì được sử dụng cho mục đích này và các thuộc tính: hibernateProperties, mappingResources và mappingDirectoryLocation phải được thiết lập. Giống như framework DAO của Spring, chúng ta có HibernateTemplate để tạo đối tượng SessionFactory. Để truy cập vào dữ liệu với HibernateTemplate, phương thức execute(HibernateCallback) phải được sử dụng. Tương tự như SessionFactory của hibernate, JDO có PersistenceManagerFactory. Nó được cấu hình bởi LocalPersistenceManagerFactoryBean. JDOTemplate cũng để tạo một đối tượng của PersistenceManagerFactory. Để truy cập vào dữ liệu với JDOTemplate, phương thức execute(JDOCallback) phải được sử dụng.  Chương 9: Giới thiệu Spring IoC. 9.1. Nguyên lý đảo ngược điều khiển Sự ra đời của Spring như là một chọn lựa khác cho EJB đã đánh dấu một bước ngoặt trong lịch sử phát triển của Enterprise Java. Theo thời gian Spring không ngừng được mở rộng với ngày càng nhiều tính năng mới. Tuy vậy, một trong những phần chủ chốt của Spring vẫn là IoC container. Đảo ngược điều khiển là một nguyên lý (hay design pattern) có từ trước khi Spring ra đời năm 2002. Nguyên lý này cũng được mô tả trong cuốn sách Design Pattern của Gang of Four với cách nói nhại theo Hollywood: "Don't call us. We'll call you" Vậy đảo ngược điều khiển là gì? Hãy xét ví dụ sau: Giả sử ta có interface Animal với phương thức là say() với ngụ ý là mỗi loài vật sẽ có tiếng kêu khác nhau. Ví dụ bò rống ò ò ò, còn chó thì sủa gâu gâu gâu. public interface Animal { void say(); } public class Cow implements Animal { public void say() { System.out.println("Cow say: oo oo oo"); } } public class Dog implements Animal { public void say() { System.out.println("Dog say: gau gau gau"); } } Theo cách truyền thống để tạo một đối tượng ta cần phải dùng lệnh như sau: Animal animal = new Dog(); animal.say(); Cách làm này có nhược điểm là nếu muốn thay đổi kiểu của animal là Cow thì cần phải viết lại code. 9.2. Tự xây dựng 1 framework đảo ngược điều khiển: Để xây dựng một framework đảo ngược điều khiển, ta dùng Java Reflection để khởi tạo đối tượng động. Trước tiên ta cần đọc file cấu hình để lấy ra thông tin về tên lớp hiện thực cần được dùng. Giả sử ta có file ioc.properties nội dung như sau: package.name = examples bean.name = Animal implementation.name = Cow Ta có interface Animal và các lớp hiện thực Cow và Dog như mô tả ở phần 1. Lớp Injector được hiện thực như sau: public class Injector { static Animal getInstance(String propertiesFile) throws FileNotFoundException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException { Animal dependency = null; Properties pros = new Properties(); pros.load(new FileInputStream(propertiesFile)); String packageName = pros.getProperty("package.name"); String beanName = pros.getProperty("bean.name"); String implementationName = pros.getProperty("implementation.name"); dependency = (Animal)Class.forName(packageName+"."+implementationName).newInstance(); return dependency; } } Cài đặt hàm main để test: public static void main(String[] args) throws FileNotFoundException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException { Properties p = System.getProperties(); String classpath = p.getProperty("java.class.path"); Animal animal = Injector.getInstance(classpath+"/examples/ioc.properties"); animal.say(); } Chạy thử ta được kết quả như sau: Cow say: oo oo oo Chương 10: Giới thiệu Hibernate. 10.1 Giới thiệu. Hibernate là một thư viện ORM(object-relational mapping) được viết bằng Java có chức năng ánh xạ từ một đối tượng được mô tả trong phần model class vào cơ sở dữ liệu quan hệ(relational database). Hibernate giải quyết tốt những vấn đề gặp phải khi ánh xạ các đối tượng, các quan hệ giữa các đối tượng với nhau, các cách thức của lập trình hướng đối tượng vào trong cơ sở dữ liệu dữ liệu quan hệ mà không quan tâm nhiều đến phần cơ sở dữ liệu bên dưới chỉ cần thao tác thông qua các lớp model. Hibernate là một thư viện mã mở được phân bố dưới dạng giấy phép LGPL(Lasser General Public License) Chức năng chính của Hibernate là ánh xạ những lớp Java xuống cơ sở dữ liệu quan hệ. Ngoài ra hibernate còn cho phép người sử dụng có thể thực hiện những câu truy vấn xuống cơ sở dữ liệu thông qua các đối tượng hoặc những câu truy vấn SQL thông thường. 10.2 Lịch sử phát triển Hibernate được phát triển bởi một nhóm lập trình Java được đứng đầu bởi Gavin King. Sau đó Jboss mới thuê nhóm này để hỗ trợ họ khi sử dụng hibernate. Hibernate trải qua rất nhiều phiên bản khác nhau đến thời điểm hiên tại đã là 3.x. Ở phiên bản này hibernate đã hỗ trợ những tính năng mới hơn như Interceptor/Callback, dữ liệu người dùng có thể định nghĩa, hỗ trợ Anotation của Java5. Hibernate 3 rất giống với EJB3.0. 10.3 Các đặt tính 10.3.1.Ánh xạ đối tượng cùng các quan hệ xuống cơ sở dữ liệu. Để ánh xạ đối tượng tương ứng bới bảng trong cơ sở dữ liệu thì hibernate sử dụng file xml để mô tả cách thức để mapping hoặc có thể sử dụng các ký pháp anotation của Java 5 để mapping trực tiếp từ đối tượng. Hibernate hỗ trợ tốt các kiêu quan hệ như one-to-manny, many-to-many giữa những lớp Java. Thêm vào đó hibernate còn có thể quản lý các mối quan hệ kết hợp, kế thừa qua lại giữa các đối tượng. Hibernate còn cho phép người dùng có thể định nghĩa ra các kiểu dữ liệu lưu trữ riêng cho mình, ngoài ra còn hỗ trợ nhiều cơ chếp ánh xạ khác như: enum, collection, ánh xạ một thuộc tính nhưng cho nhiều bảng khác nhau 10.3.2.Tính persistence: Hibernate cung cắp khả năng thực hiện việc ánh xạ các lớp Java(POJOs) xuống cơ sở dữ liệu một cách trong suốt chỉ đòi hỏi các lớp Java có constructor không tham số và các thuộc tính của nó không được ở dạng public trong một vài trường hợp đặt biệt thì cần viết lại 2 hàm hashCode và equals. Hibernate hỗ trợ việc truy suất dữ liệu theo nhóm(Collection), tập hợp(Set), danh sach(List)…. rất tốt ngoài ra còn hỗ trợ phần generics trong Java5 và hỗ trợ phần lazy load đối với việc truy suất dữ liệu nhiều. 10.3.3.Ngôn ngữ truy vấn đối tượng(HQL) Hibernate cho phép người dùng thực hiện các câu truy vấn ngay trên đối tượng mà không cần phải viết lại các câu SQL. Hibernate còn cung cắp một bộ Criteria Queries hỗ trợ việc thực hiện truy vấn theo cách của người lập trình hương đối tượng. 10.3.4 Khả năng tương thích Từ khi hibernate ra đời đã làm một sự thay đổi lớn đối với những người lập trình hướng cơ sở dư liệu. Giờ đây hibernate hầu như được hỗ trợ trong tất cả các framework chính như: spring, struts, jsf, tabestry, webwork... Không chỉ giới hạn trong việc hỗ trợ cho những người phát triển java mà giờ đây hibernate còn hỗ trợ cho cả những người lập trình theo công nghệ của .net(Nhibernate). 10.3.5 Khả năng tích hợp Hibernate có thể chạy trên hầu hết các môi trường khác nhau từ ứng dụng đơn(stand alone), đến những ứng dụng Java thương mại sử dụng servlet container, application server, EJB container. Chương 11: Giới thiệu Apache Shiro. 11.1 Kiến trúc Apache Shiro: Mục tiêu thiết kế của Apache Shiro là để đơn giản hóa bảo mật ứng dụng bằng cách trực quan và dễ sử dụng. Mô hình thiết kế cốt lõi của Shiro là để cho mọi người biết như thế nào là ứng dụng bảo mật. Các phần mềm ứng dụng thường được thiết kế dựa trên nhu cầu của người sử dụng. Đó là, bạn thường sẽ thiết kế giao diện người dùng hoặc dịch vụ API dựa trên cách mà một user tương tác với phần mềm. Ví dụ, bạn có thể nói, "Nếu một user tương tác với ứng dụng của ta là đăng nhập vào, ta sẽ cho họ thấy một nút mà họ có thể kích vào để xem thông tin tài khoản của họ. Nếu họ không đăng nhập vào, ta sẽ hiển thị một nút đăng ký. " Các ví dụ trên cho ta thấy rằng hầu hết các ứng dụng được viết ra để thỏa mãn nhu cầu của user. Thậm chí, ngay khi user là một phần mềm hay là một cái gì đó không phải là do con người, bạn vẫn có thể viết code để phản ánh những tương tác của con người hay của phần mềm đang tương tác với ứng dụng Shiro phản ánh các khái niệm này trong mỗi cách thiết kế riêng của nó. Bằng cách kết hợp những gì đã trực quan cho các nhà phát triền phần mềm Apache Shiro vẫn còn trực quan và dễ dàng để sử dụng trong bất kỳ ứng dụng thực tế khác nữa. 11.2 Tổng quan Apache Shiro: Ở mức khái niệm tổng quan nhất, kiến trúc của Apache có ba khái niệm chính: The Subject, SecurityManger và Realms. Subject: về bản chất, Subject được hiểu như là một cái gì đó ở tầng lớp “view” của user đang thực thi ứng dụng. SecurityManager: SecurityManager là trái tim của kiến trúc Shiro. Realms: như là cầu nối giữa Shiro và dữ liệu đã được bảo mật của bạn. Khi nói đến thời gian thực sự để tương tác với dữ liệu liên quan đến bảo mật như tài khoản người dùng để Authentication (login) và Authorization (access control), tìm kiếm những thứ này từ một hoặc nhiều Realms cấu hình cho một ứng dụng. Trong hoàn cảnh này Realm  là một bản chất của security-specific  DAO: tóm lượt các chi tiết kết nối cho cácdata source và kết hợp các data có sẵn khi Shiro cần dung đến các data này. 11.3 Kiến trúc chi tiết: Subject (org.apache.shiro.subject.Subject ): lớp bảo mật “View ”của thực thể đang tương tác với ứng dụng. SecurityManager(org.apache.shiro.mgt.SecurityManager): là trái tim của kiến trúc Shiro. Nó quản lý các thành phần bên trong để luôn đảm bảo rằng chúng luôn hoạt động tốt với nhau. Và nó cũng quản lý mức “View” của mỗi ứng dụng của mỗi user, để nó biết được các hoạt động bảo mật trên từng user được thực thi như thế nào. Authenticator(org.apache.shiro.authc.Authenticator): là thành phần có nhiệm vụ thực thi và phản ứng để xác thực các Authentication (login). Khi một user login, việc login này được thực hiện bởi Authentication. Authentication biết cách nào để phối hợp một hay nhiều Realms thích hợp với thông tin user. Những dữ liệu thu được từ các Realms được dùng để xác thực ID của uer. Authentication strategy (org.apache.shiro.authc.pam.AuthenticationStrategy): cần thiết cho việc cấu hình nhiều Realms cùng lúc. Authorizer (org.apache.shiro.authz.Authorizer):thành phần kiểm soát việc truy cập của user. Đó là cơ chế cuối cùng mà sau khi thực hiện việc này, user có quyền được thực hiện việc gì đó hay không. SessionManager (org.apache.shiro.session.mgt.SessionManager): SessionManager biết làm thế nào để tạo và quản lý một vòng đời Session của một user. Đây là tính năng duy nhất trong các Security Framework - Shiro có khả năng quản lý phiên user trong bất cứ môi trường nào, ngay cả khi không có Web / Servlet hoặc EJB container có sẵn.  Theo mặc định, Shiro sẽ sử dụng một cơ chế session đang tồn tại nếu có, (ví dụ Servlet Container), nhưng nếu không có, chẳng hạn như trong một môi trường ứng dụng web độc lập, nó sẽ sử dụng các built-in sẵn có trong trình quản lý session để đưa ra các kinh nghiệm lập trình. SessionDAO tồn tại để cho phép bất kỳ nguồn dữ liệu được sử dụng để tiếp tục session. CacheManager (org.apache.shiro.cache.CacheManager) : CacheManager tạo ra và quản lý vòng đời cache được sử dụng bởi các thành phần Shiro khác. Bởi vì Shiro có thể truy cập vào nhiều nguồn dữ liệu back-end cho việc authentication, xác thực và quản lý session, Cache luôn là lớp đầu tiên trong framework để cải thiện hiệu suất trong khi sử dụng các nguồn dữ liệu. Crytography (org.apache.shiro.crypto.*): là một sự bổ sung tự nhiên vào một security framefwork. Gói Shiro Crypto bao gồm easy-to-use và các thuật toán crytographi Ciphers, Hashes,… Tất cả các lớp trong gói phần mềm này được thiết kế cẩn thận rất dễ sử dụng và dễ hiểu. Bất cứ ai đã sử dụng hỗ trợ mã hóa bản địa của Java biết rằng nó có thể là một con vật đầy thử thách để chế ngự. Shiro crypto API đơn giản hóa cơ chế phức tạp của JAVA và Cryptography dễ dàng để sử dụng cho con người bình thường. Realms ( org.apache.shiro.realm.Realm ): Realms hoạt động như một cầu nối giữa Shiro và dữ liệu bảo mật của ứng dụng của bạn. Bạn có thể cấu hình nhiều Realms nếu cần thiết (thường là một cho một Data Source) và Shiro sẽ phối hợp chúng lại với nhau nếu cần thiết cho cả xác thực (authentication) và ủy quyền (authorization). 11.4 SecurityManager: Ứng dụng của SecurityManager là thực thi các hoạt động bảo mật hệ thống và quản lý  đối với tất cả ứng dụng. Mặc định thì Shiro SecurityManager bao gồm: Authentication. Authorization. Session Management. Cache Management. Realms coordination. Event propagation. “Remember Me” services. Subject Creation. Logout. … Chương 12: Tổng quan hệ thống quản lý cán bộ công chức 12.1 Mô hình ERD: 12.2 Use-case: 12.3 Giao diện: Tài liệu tham khảo: Phần mềm có sử dụng một số lib do công ty cổ phần tin học giải pháp tích hợp mở cung cấp.

Các file đính kèm theo tài liệu này:

  • docbao_cao_htqlcbcc_2398.doc