Declarative:
- Không cần lập trình mà chỉ mô tả thông tin qua deployment descriptor.
- Deployment descriptor mô tả và thông báo cho container các roles về security
và security constraints để client truy cập các phương thức phải tuân theo qui
tắc bảo mật. Đặc biệt container sẽ hỗ trợ cơ chế security cho các ứng dụng
được deploy vào container
- Cấu hình security cho ứng dụng EJB deploy trên server Jboss.
52 trang |
Chia sẻ: lylyngoc | Lượt xem: 6019 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Đề tài Enterprice Java Bean (EJB), để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ssion của giao diện QueueConnection để
tạo ra một đối tượng QueueSession như mã sau:
session = connection.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
chú ý rằng bạn chọn false cho tham số đầu tiên của hàm createQueueSession là để
biểu thị rằng bạn không tạo ra một đối tượng transactional session.
Tiếp theo, bạn có thể gọi hàm createSender của interface QueueSession. Tham số
truyền vào là một đối tượng Queue. Giá trị trả về của hàm này là một đối tượng tạo
ra message. Đó là một QueueSender.
sender = session.createSender(queue);
sau đó, một đối tượng TextMessage dựa trên các Message nhận được bằng cách
duyệt qua các Text của TextMessage để gọi hàm createTextMessage của đối tượng
QueueSession và sau đó gán text cho đối tượng TextMessage.
13 | T r a n g
TextMessage msg = session.createTextMessage( );
msg.setText("This is my sent message " + (i + 1));
bây giờ, Message đã sẵn sàng được gửi. chúng ta có thể gửi Message bằng cách
gọi hàm send của đối tượng QueueSender:
sender.send(msg);
quá trình kết nối của MDBs có thể được thấy giống với sơ đồ sau:
Hàm đặc tả @Resource đặc tả sự phụ thuộc vào một tài nguyên bên ngoài như một
nguồn dữ liệu JDBC hoặc một đích đến JMS hoặc một connection factory.
Nếu bạn sử dụng các chú thích (annotation) vào một class thì chú thích đó sẽ khai
báo tài nguyên mà bean sẽ cần tìm kiếm khi khởi chạy.
Tham số mappedName của chú thích Resource đặc tả một tên JNDI toàn cục của
các tài nguyên lệ thuộc. ví dụ:
@Resource(mappedName ="jms/Queue")
Đặc tả tên JNDI của tài nguyên lệ thuộc là jms/Queue và được triển khai trên máy
chủ JEE.
Trong một ứng dụng web-client, tham số "jms/Queue" và “ConnectionFactory”
đã được sử dụng trong JNDI lookup. Cả hai cái tên JNDI và sử dụng cacs kết nối từ
14 | T r a n g
bên ngoài được cung cấp bởi các bộ chuyển đổi tài nguyên JMS. Việc thực hiện tìm
kiếm JNDI để sử dụng cho một dịch vụ web như sau:
InitialContext ctx = new InitialContext();
queue = (Queue) ctx.lookup("jms/Queue");
QueueConnectionFactory factory =
(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
connection = factory.createQueueConnection();
session = cnn.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
Code cho message-driven bean:
package mdb;
import javax.ejb.*;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import java.text.*;
import javax.naming.*;
import java.util.logging.Logger;
@MessageDriven(mappedName="jms/Queue")
public class MessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdc;
private static final Logger logger;
public void onMessage(Message msg) {
TextMessage tmsg = null;
try {
15 | T r a n g
tmsg = (TextMessage) msg;
logger.info("MESSAGE BEAN: Message received: " + tmsg.getText( ));
System.out.println ("The onMessage() is called");
} catch (JMSException e) {
e.printStackTrace( );
mdc.setRollbackOnly( );
}
catch (Throwable th) {
th.printStackTrace();
}
}
public void ejbRemove( )throws EJBException{
loger.fine("ejbRemove()");
}
}
Lớp MessageBean thể hiện các yêu cầu dưới đây:
Trong EJB 3.0, lớp MDB được chú thích với @MessageDriven mà đặc tả các
message queue theo dõi MDB (ví dụ: jms/Queue). Nếu hàng đợi không tồn tại, các
EJB container tự động tạo ra nó ở thời gian triển khai. Không có tập tin cấu hình XML
cần thiết!
Đối với các máy chủ ứng dụng, các chú thích @MessageDriven thường chứa một
thuộc tính mappedName chỉ định tên JNDI của điểm đích mà từ đó, các bean sẽ xử lý
các message.
Các class phải được đặt ở chế độ public và phải có một public constructor mặc
định. Nó không phải định nghĩa ra các hàm finalize.
Một lớp MDB nên thực thi interface MessageListener cho các loại Message mà
nó hỗ trợ. Interface này định nghĩa một hàm duy nhất đó là hàm onMessage(). Khi
EJB container nhận một message, nó gọi hàm onMessage() của message-driven-bean
đê xử lý các thông điệp. Hàm onMessage() chưa các bussiness logic và điều khiển các
quá trình xử lý của message phù hợp với các ứng dụng. nó có thể gọi các hàm giúp
16 | T r a n g
đỡ hoặc gọi một session bean để xử lý thông tin trong message hoặc lưu trữ nó trong
cơ sở dữ liệu.
Một message được được gửi đến một message-driven bean với một transaction
context, do đó, tất cả các hoạt động trong hàm onMessage() là một phần của một
transaction. Nếu message nào đang xử lý mà bị hủy, nó sẽ được nạp lại.
Trong ví dụ của chúng ta, hàm MessageBean.onMessage( ) truy xuất đến phần
thân của thông điệp, phân tách các thông điệp thành một TextMessage, thực hiện các
hàm logic cần thiết và hiển thị văn bản cho message-client.
II. JAVA PERSISTENCE API
2.1. JDBC và ORM
Trong phần này chúng ta sẽ so sánh sự giống và khác nhau giữa công nghệ JDBC
và công nghệ ORM. Cả 2 công nghệ này đều dùng để lưu trữ CSDL vào kho lưu trữ
lâu dài để dùng về sau.
2.1.1. JDBC là gì?
JDBC là từ viết tắt cho Java Database Connectindentification variableity, là
một tập các Java API dùng cho việc truy xuất vào các cơ sở dữ liệu quan hệ từ
chương trình Java. Java API cho phép lập trình viên có thể thực thi các công lệnh
SQL để lấy, truy vấn, lưu trữ dữ liệu từ database.
JDBC cho phép nhanh chóng phát triển các ứng dụng Java nhỏ có sử dụng
CSDL. Lập trình viên phải viết code để kết nối đến CSDL sử dụng Connection
String (Connection URL) sau đó viết code để truy vấn câu lệnh SQL. Sau khi truy
vấn thành công, một tập dữ liệu được trả về từ CSDL, người lập trình cần đọc
những data này sau đó xử lý để trả về tập các đối tượng mong muốn.
- Ưu điểm của JDBC:
Rõ ràng và dễ dàng, sử dụng tốt cho chương trình nhỏ
JDBC có hiệu suất cao khi làm việc với một lượng lớn dữ liệu
- Nhược điểm của JDBC
JDBC sẽ khó sử dụng trong những dự án lớn
Lập trình viên phải tự code phần Transaction và Concurrency trong
chương trình
17 | T r a n g
Khó khăn trong vấn đề quản lý kết nối và mở đóng kết nối tới CSDL
(đặc biệt là việc đóng kết nối)
2.1.2. ORM là gì?
ORM viết tắt cho Object Relation Mapping, là một công nghệ khác của Java
dùng để truy xuất vào CSDL. Bằng công nghệ này những đối tượng business sẽ
được ánh xạ từ/tới các bảng trong CSDL với sự giúp đỡ của ORM framework.
- Ưu điểm của ORM
Không cần làm việc trực tiếp với câu lệnh SQL để lưu trữ và truy vấn dữ
liệu
Cấu hình đơn giản, hỗ trỡ cấu hình logging
API chuẩn dùng cho các đối tượng business
Giúp phát triển ứng dụng nhanh chóng
Dễ học và dễ dùng
- Nhược điểm của ORM
Hiệu xuất chậm khi có một lượng lớn dữ liệu update
Chậm hơn một chút so với JDBC
2.2. JPA là gì?
Java Persistence API (JPA) là một đặc tả Java dùng cho việc truy xuất, lưu trữ/truy
vấn và quản lý dữ liệu giữa các đối tượng Java/class với CSDL quan hệ. JPA được
định nghĩa là một phần của đặc tả EJB 3.0 như là thay thế cho đặc tả EJB 2CMP
Entity Bean. JPA đang được cân nhắc trở thành chuẩn trong cách tiếp cận Object to
Relation Mapping (ORM) trong ngành công nghiệp Java. JPA chỉ là một đặc tả, nó
không phải là một sản phẩm và không thể tự thực hiện việc lưu trữ/truy vấn. JPA chỉ
là một tập hợp các interface cần được cài đặt.
Có rất nhiều open source và các phiên bản thương mại cài đặt JPA mà chúng ta có
thể chọn để sử dụng trong các ứng dụng Java EE5. JPA cho phép POJO (Plain Old
Java Object) dễ dàng lưu trữ /truy xuất mà không cần cài đặt bất cứ interface hoặc
phương thức nào.Thông qua JPA, nhà phát triển có thể ánh xạ (map), lưu trữ, cập nhật
và lấy dữ liệu từ CSDL thành Java object và ngược lại. JPA cho phép việc khai báo
maping đối tượng có thể được sử dụng thông qua chú thích (annotation) hoặc thông
qua XML. Một cấu hình XML sẽ ghi dè lên annotation.
18 | T r a n g
JPA cũng định nghĩa một đối tượng Runtime EntityManager API dùng cho việc
truy vấn và transaction các đối tượng với CSDL. JPA định nghĩa một ngôn ngữ truy
vấn theo mức độ Object JPQL dùng để thực hiện các truy vấn với CSDL.
Ngày nay, các hãng công nghệ thường phát hành bàn cài đặt JPA đi kèm với
framework của họ. Do đó, nhà phát triển có thể chọn một cài đặt ORM nào phù hợp
nhất với yêu cầu của ứng dụng. Ví dụ, sản phẩm có thể được bắt đầu từ một phiên bản
ORM miễn phí sau đó có thể chuyển đổi sang một phiên bản ORM thương mại. Việc
chuyển đổi này không hề làm thay đổi code.Tính độc lập của ORM framework cũng
là một lợi ích to lớn của JPA.
- ORM framework: dưới đây là danh sách các ORM framework sử dụng đặc tả JPA:
Hibernate (Red Hat – Open Source)
Toplink (Oracle – Commercial)
EclipseLink (Eclipse –Open Source)
Open JPA (Apache – Open Source)
- Tại sao nên sử dụng JPA?
JPA là một đặc tả chuẩn và là một phần của đặc tả EJB3.
Rất nhiều ORM framework miễn phí có thể dùng để phát triển ứng dụng ở
nhiều quy mô khác nhau.
Ứng dụng mang tích thích ứng cao với nhiều server và nhiều ORM
framework.
Có thể dùng ở cả ứng dụng JEE và JSE.
Tính năng annotation trong JSE5 có thể được sử dụng.
Hỗ trợ cấu hình dùng cả annotation và XML.
Hỗ trợ bởi nhiều hãng công nghệ lớn.
- Phiên bản của đặc tả JPA?
JPA 1.0 được phát hành vào 11/5/2006.
JPA 2.0 được phát hành vào 10/12/2009.
2.3. Entity
2.3.1. Persistence Entity
Persistence data chỉ đến những dữ liệu được lưu trữ lâu dài trong ứng dụng.
Trạng thái của những dữ liệu này được lâu dài là do chúng được lưu trữ trong các
kho lưu trữ lâu dài như CSDL, file. Trong JPA, những persistence data này được
19 | T r a n g
xem như các entity. Một entity là một tập hợp các dữ liệu logic mà ta có thể lưu
trữ và lấy được. Ví dụ trong ứng dụng ngân hàng, khách hàng và tài khoản được
xem như là các entity. Tên khách hàng, địa chỉ khách hàng là những thông tin
logic được nhóm lại với nhau đại diện cho entity Khách hàng. Tương tự, số tài
khoản, số tiền trong tài khoản … là những thông tin logic được nhóm lại dưới
entity Tài khoản.
2.3.2. Entity
Trong đặc tả JPA, một Entity được xem là một persistent object mà nó có thể
được lưu trữ và lấy ra từ persistent storage (CSDL). Trong kỹ thuật lập trình, một
entity sẽ tương ứng với một class Java (đối tượng kiểu POJO - plain old java
object). Lớp này đại diện cho một bảng (table) trong CSDL còn thể hiện của class
(instance) tương ứng cho một dòng (record) của bảng.
POJO là khái niệm trong Java dùng để chỉ những đối tượng Java không kế
thừa và cài đặt từ một số lớp đặc biệt. Do đó, phần lớn các đối tượng Java bình
thường đều là POJO.
Ví dụ về lớp không phải POJO
Trong ví dụ trên, cả Myservlet và MyRemote đều kế thừa và cài đặt các lớp
đặc biệt Servlet và Bean nên các lớp này không phải POJO.
- Yêu cầu đối với Entity
Được chú thích với annotation javax.persistence.Entity
Khai báo lớp public hoặc protected và không có constructor có tham số
Class không được khai báo final
Không có phương thức hoặc biến persistence nào được khai báo final
Một entity có thể kế thừa từ một lớp entity khác hoặc một lớp không
phải entity
Một lớp không phải entity có thể kế thừa từ một lớp entity
- Field và Property
20 | T r a n g
Có thể truy xuất trạng thái của entity thông qua biến hoặc thông qua
JavaBeans –style properties (getters/ setters). Các kiểu dữ liệu hỗ trợ bao
gồm các kiểu dữ liệu cơ bản trong java, kiểu enum, các entity hoặc tập hợp
các entity khác.Các trường được chú thích với @Transient sẽ không được
lưu trữ vào kho dữ liệu
- Khóa chính của Entity
Mỗi entity sẽ có một unique object identifier (tương ứng với Persistence
identifier). Khai báo persistence identifier bằng cách thêm @Id vào trước
trường (có thể thêm trước 1 trường trong trường hợp 1 khóa chính hoặc
nhiều trường trong trường hợp bảng có nhiều khóa chính)
Ví dụ :
Ta khai báo lớp MobileEntity bình thường nhưng để trở thành Entity ta
thêm chú thích @Entity vào trước khai báo lớp. Để khai báo persistence
ID ta thêm chú thích @Id vào trước trường muốn làm khóa chính (primary
key), trường hợp này là imeiNo (số imei).
Entity này sẽ tương ứng với một bảng trong CSDL có tính chất sau :
Tên Table – MOBILEENTITY
Tên Column– [MODEL, MAUNFACTURER, PRICE and IMEINO]
(Tương ứng với biến trong entity).
- Phát sinh tự động ID
ID có thể tự động tạo ra trong CSDL bằng cách thêm vào chú thích
@GeneratedValue trước trường ID.
Ví dụ:
21 | T r a n g
- Tùy biến Entity
Thay đổi tên bảng mặc định
Theo mặc định tên bảng sẽ trùng với tên class Entity. Chúng ta có thể thay
đổi điều này bằng các thêm tên bảng vào chú thích @Entity
Ví dụ:
Bây giờ tên bảng là MOBILE_ENTITY và chúng ta phải sử dụng tên này
để thực hiện truy vấn về sau.
Tùy biến cột
Ta sử dụng chú thích @Column để tùy biến tên cột, size dữ liệu, thuộc tính
nullable…
Ví dụ:
- Mối quan hệ giữa các Entity
JPA hỗ trợ 4 kiểu quan hệ giữa các entity bao gồm:
One-to-one: Entity sử dụng annotation này sẽ tham chiếu đến duy nhất
một entity đích và ngược lại
Ví dụ:
22 | T r a n g
One-to-many: Entity sử dụng annotation này sẽ tham chiếu đến nhiều
entity đích nhưng những entity đích không thể tham chiếu đến nhiều
entity nguồn.
Ví dụ:
Many-to-one : ngược lại với mối quan hệ One-to-many. Entity sử dụng
annotation này sẽ tham chiếu duy nhất đến một entity đích trong khi
entity đích này lại được tham chiếu bởi nhiều entity (kiểu trùng với kiểu
của entity nguồn).
Ví dụ:
23 | T r a n g
Many-to-many: Một entity kiểu này có mối quan hệ 1 hoặc nhiều với
entity kiểu khác và ngược lại.
Ví dụ:
2.4. Persistence Context
Một persistent context là một tập hợp các entity được quản lý bởi EntityManager.
Persistence context đánh dấu sự thay đổi của các entity đó. EntityManager hỗ trợ
persistence context để commit hoặc undo những thay đổi. Ngay khi một
EntityManager object được tạo ra, nó ngầm được liên kết với một persistence context
để phục vụ cho việc quản lý tập các entity. Một persistence context sẽ định nghĩa
một giới hạn mà ở đó các đối tượng entity nào sẽ được tạo ra, lưu trữ hoặc hủy bỏ.
24 | T r a n g
Hình: Quan hệ giữa Persistence Context và EntityManager
2.5. Entity Manager
EntityManager (javax.persistence.EntityManager) hỗ trợ việc quản lý các entity,
hỗ trợ các phương thức để lưu trữ, truy vấn và xóa các entity.
Trong J2SE, một tham chiếu tới một entity manager có thể được tạo ra nhờ sử
dụng entity manager factory (javax.persistence.EntityManagerFactory) và lớp
Persistence. Lớp Persistence (javax.persistence.Persistence) là lớp helper dùng để tạo
ra đối tượng EntityManagerFactory sau đó nhờ đối tượng này ta tạo được một đối
tượng EntityManager. Một đối tượng EntityManager sẽ ngầm có liên kết với một
persistence context.
Ví dụ :
Trong J2EE, container đã tự động thêm một tham chiếu tới EntityManager nên
việc sử dụng rất đơn giản
2.5.1. Thao tác với Entity
25 | T r a n g
- Persistence Entity
Các đối tượng entity cũng được xem như các đối tượng java bình thường cho
đến khi chúng được quản lý và persistence bởi EntityManager. Đoạn code sau
đây làm cho một entity được quản lý bởi EntityManager.
Phương thức persist(entityObject) làm cho entity tạo được mối liên kết với
CSDL và thuộc sự quản lý quản lý của persistence context của EntityManager.
Khi phương thức này được gọi, persistence engine sẽ kiểm tra sự tồn tại duy
nhất của object bằng các sử dụng indentifier ( đại diện cho primary key). Nếu có
sự trùng ID của 2 object bất kỳ, một runtime Exception (EntityExistsException)
sẽ được ném ra.
- Sử dụng EntityManger
EntityManger cung cấp một số phương thức cơ bản để thao tác với các Entity
được liệt kê dưới đây.
contains() : kiểm tra xem entity có được quản lý bởi by Persistence
context
flush(): Đồng bộ từ persistence context tới database
merge(): Đồng bộ một detached entity với p/c
remove(): Xóa một entity khỏi database và persistence context
refresh(): Load lại các entity từ database
find(): Tìm kiếm entity dựa trên primary key, nếu không tìm thấy sẽ trả
về null
Ví dụ :
26 | T r a n g
- Truy vấn entity
Nhà phát triển có thể dùng EntityManager phục vụ cho những câu truy vấn
đơn giản hoặc sử dụng đối tượng Query để cung cấp chứng năng truy vấn nâng
cao nhằm lấy được các entity mong muốn.
2.5.2. Persistence Unit
Persistence Unit định nghĩa một tập các lớp entity được quản lý bởi một thể
hiện của EntityManager trong ứng dụng. Mỗi Persistence unit có thể có database
provider và database drindentification variableer khác nhau. File cấu hình
persistence.xml là file chứa thông tin cấu hình persistence unit.
Ví dụ :
2.6. Java Persistence Query Language
2.6.1. JPQL là gì
Java Persistence Query Language (JPQL) là một ngôn ngữ truy vấn kiểu
hướng đối tượng không phụ thuộc vào nền tảng (platform-independent object-
oriented query language) , là một phần của đặc tả Java Persistence API (JPA).
JPQL dùng để tạo các cấu lệnh truy vấn với các entity lưu trữ trong
27 | T r a n g
CSDL.Persistence engine sẽ chuyển đổi từ JPQL sang SQL Native variablee
trước khi thực thi.
2.6.2. Cấu trúc truy vấn JPQL
Cú pháp của JPQL rất giống với cú pháp của SQL. Điều này tạo sự thuận
lợi lớn vì SQL là ngôn ngữ truy vấn mạnh và rất gần gũi, quen thuộc với lập trình
viên.
Điểm khác nhau chính giữa SQL và JPQL đó là SQL làm việc với các bảng,
các dòng và các trường dữ liệu trong CSDL còn JPQL làm việc với các class và
object Java. Do đó JPQL có thể truy vấn để lấy về một danh sách các object entity
hơn là trả về dữ liệu các trường của bảng như trong SQL. Điều này làm trong
JPQL trở nên thân thiện và dễ dùng hơn trong Java.
Như SQL, JPQL cũng có 6 mệnh đề chính:
Trong đó SELECT và FROM là 2 mệnh đề bắt buộc còn GROUP BY,
HAVING và ORDER BY là tùy chọn.
Cấu trúc truy vấn DELETE và UPDATE đơn giản hơn
JPQL là ngôn ngữ phân biệt hoa thường (trừ từ khóa không phân biệt hoa
thường) có nghĩa là trong câu lệnh truy vấn sử dụng chuỗi “ORM” sẽ khác với
“orm”.
Câu lệnh JPQL cơ bản: sẽ bao gồm 2 mệnh đề chính SELECT và FROM.
Trong mệnh đề FROM sẽ khia báo 1 hoặc nhiều biến truy vấn. Biến truy vấn
tương tự như biến lặp trong ngôn ngữ lập trình. Một biến truy vấn sẽ lặp qua tất
28 | T r a n g
cả các object trong CSDL. Một biến truy vấn sẽ được ghép vào một class entity
để xác định miền giá trị của biến.
- Identifier: Chuỗi ký tự không giới hạn chiều dài chuỗi. Phù hợp với quy tắc
đặt tên định danh của Java (không bắt đầu bằng số, khoảng trắng; được phép
chứa dấu gạch dưới và $,…). Một số định danh được dành riêng cho JPQL:
SELECT, FROM, WHERE, UPDATE, DELETE, JOIN, GROUP,BY,
HAVING …
- Identification Variable: là một định danh hợp lệ được khai báo trong mệnh
đề FROM của câu truy vấn; nó không được trùng với các định danh dành
riêng hoặc tên trùng với bất kỳ entity nào trong cùng persistence unit.
Identification Variables phân biệt hoa thường, được dùng để đánh giá giá trị
của biểu thức đã được dùng để khai báo biến.
Một indentification variable được dùng để tham chiếu tới một thể hiện của
một entity hoặc một phần tử trong một tập hợp các entity thuộc về một kiểu
schema nhất định.
Ví dụ:
SELECT DISTINCT mag FROM Magazine mag JOIN mag.articles art JOIN
art.author auth WHERE auth.firstName = 'John'
Trong khai báo của mệnh đề FROM mag.articles art thì indentification
variable art đánh giá giá trị của bất kỳ Article nào liên quan đến Magazine.
Trường quan hệ articles là một tập hợp các thể hiện của schema kiểu
Article và indentification variable art tham chiếu đến một phần tử của tập
hợp này.Kiểu của biến auth là kiểu schema Author và biến này tham chiếu
đến một entity kiểu Author.
- Range Variable
Khai báo một indentification variable như là một range variable bằng các dùng
từ khóa AS như trong SQL. Được dùng trong trường hợp cần so sánh nhiều
thực thể của một kiểu schema.
range_variable_declaration ::= abstract_schema_name [AS]
identification_variable
29 | T r a n g
Ví dụ:
SELECT DISTINCT mag1 FROM Magazine as mag1, Magazine as mag2
WHERE mag1.price > mag2.price AND mag2.publisher.name = 'Adventure'
Ví dụ này thể hiện việc sử dụng hai indentification variable (mag1, mag2)
trong mệnh đề FROM cùng kiểu schema Magazine.Kết quả trả về là là tập
hợp các Magazine có giá lớn hơn giá của các magazine được phát hành bới
“Adventure” publisher.
- Truy vấn JPQL giống với truy vấn SQL, sử dụng Identification Variable và
Range Variable.
2.6.3. Các kiểu query
Lớp EntityManager hỗ trợ một số phương thức để tạo ra query như sau:
EntityManager.createNamedQuery (static query)
EntityManager.createQuery (dynamic query)
EntityManager.createNativeQuery (Native variablee query)
Trong JPA, query có một số kiểu chính như sau:
- Static query
Ta sử dụng annotation @NamedQuery (javax.persistence.NamedQuery) để khai
báo một static query. Trong đó thành phần @NameQuery có 2 thành phần chính:
name: tên của Query dùng với phương thức createNamedQuery.
query: chuỗi truy vấn
Ví dụ:
@NamedQuery(name="findAllCustomers",
query="SELECT c FROM Customer")
@NamedQuery(name="findAllCustomers",
query="SELECT c FROM Customer")
Ta có thể dùng @NamedQueries (javax.persistence.NamedQueries) annotation
để khai báo nhiều named query.
30 | T r a n g
Ví dụ:
@NamedQueries( {
@NamedQuery(name = “Mobile.selectAllQuery”
query = “SELECT M FROM MOBILEENTITY”),
@NamedQuery(name = “Mobile.deleteAllQuery”
query = “DELETE M FROM MOBILEENTITY”)
} )
- Dymanic Query
Dynamic query là những query được định nghĩa trực tiếp trong layer business
logic của ứng dụng. Persistence engine sẽ parse, kiểm tra hợp lệ và map JPQL
thành SQL tại thời điểm chạy.
Ví dụ:
public List findAll(String entityName){
return entityManager.createQuery(
"select e from " + entityName + " e")
.getResultList();
}
Chúng ta có thể thiết lập tham số cho câu lệnh truy vấn bằng cách sử dụng Named
Parameter. Named Parameter trong câu truy vấn sẽ được đặt sau dấu hai chấm
(:). Để truyền các giá trị vào tham số ta sử dụng phương thức setParameter của
interface javax.persistence.Query
Query.setParameter(String name, Object value)
Ví dụ:
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.getResultList();
31 | T r a n g
}
Ta cũng có thể thiết lập tham số sử dụng Positional Parameter (tham số theo
vị trí) bằng các sử dụng một dấu chấm hỏi (?) theo sau đó là vị trí của
parameter.
Để truyền giá trị cho tham số ta sử dụng phương thức:
Query.setParameter(integer position, Object value)
Ví dụ:
public List findWithName(String name) {
return em.createQuery(
“SELECT c FROM Customer c WHERE c.name LIKE ?1”)
.setParameter(1, name)
.getResultList();
}
- Native Query
Lệnh truy vấn được hiển thị như câu lệnh Native SQL. Có thể gọi store
procedure bằng cách dùng cú pháp “call procname”.
Ví dụ:
Query q = entityManager.createNativeQuery(
"SELECT o.id, o.quantity, o.item " +
"FROM Order o, Item i " +
"WHERE (o.item = i.id) AND (i.name = 'widget')");
Thao tác query
Thao tác kết quả trả về
Multiple Result: Query.getResultList: sẽ thực hiện một câu truy vấn và
trả về một danh sách (list) các instance entity thỏa mãn điều kiện truy
vấn.
Ví dụ:
32 | T r a n g
Query query = entityManager.createQuery("SELECT c FROM Country
c");
List results = query.getResultList();
Thao tác getResultList chỉ thực thi được với câu lệnh SELECT, nếu sử
dựng lệnh Update hoặc DELETE sẽ ném ra một ngoại lệ
IllegalStateException.
Single Result: Query.getSingleResult: sẽ truy vấn và trả về một đối
tượng đơn.
Ví dụ:
Query singleSelectQuery = entityManager.createQuery(
“SELECT C FROM CUSTOMER WHERE C.ID = ‘ABC-123’”);
Customer custObj = singleSelectQuery.getSingleResult();
Nếu không tìm thấy thì ngoại lệ EntityNotFoundException sẽ được ném
ra. Nếu tìm thấy nhiều hơn một đối tượng entity thì một ngoại lệ
NonUniqueResultException cũng được ném ra.
Tùy biến tập giá trị trả về: Để tùy biến tập trả về ta sử dụng các phương
thức sau:
+ setFirstResult() – đặt thứ tự đầu tiên của tập cần lấy trong tập kết quả trả
về
+ setMaxResults() – thiết lập số phần tử cần lấy
Ví dụ:
int maxRecords = 5; int startPosition = 0;
String queryString = “SELECT M FROM MOBILEENTITY”;
Query selectQuery = entityManager.createQuery(queryString);
selectQuery.setMaxResults(maxRecords);
selectQuery.setFirstResult(startPosition);
List mobiles =
entityManager.getResultList(queryString);
Thực thi DELETE và UPDATE
Delete và update sẽ được thực thi qua phương thức executeUpdate
Ví dụ:
33 | T r a n g
int count = em.createQuery("DELETE FROM Country").executeUpdate();
int count = em.createQuery("UPDATE Country SET area =
0").executeUpdate();
Nếu thành công, phương thức executeUpdate trả về số lượng các phần tử đã
được update hoặc xóa trong câu lệnh truy vấn.
III. Transaction trong EJB
Một trong những tính năng chính của kỹ thuật EJB là hỗ trợ distributed transaction.
Kỹ thuật EJB cho phép một nhà phát triển viết một ứng dụng update dữ liệu từ nhiều cở
sở dữ liệu được phân tán ở nhiều site. Các site có thể sử dụng các EJB server từ các nhà
cung cấp khác nhau.
Phần này đưa ra cách nhìn tổng quan về transaction và quản lý transaction trong EJB.
3.1. Transactions
Transaction đại diện cho một nhóm các hoạt động phải được thực hiện như là một
đơn vị công việc đơn lẻ. Một transaction được hoàn tất khi và chỉ khi tất cả các mục
công việc trong một nhóm công việc cho ra kết quả thành công. Nếu bất kỳ mục công
việc nào thất bại thì transaction bị coi là thất bại.
Sử dụng transaction giúp đơn giản hóa lập trình ứng dụng. Transaction giải phóng
người lập trình khỏi các vấn đề phức tạp của phục hồi sai sót và lập trình đa người
dùng. Người lập trình sử dụng transaction bằng cách phân chia các công việc của
ứng dụng vào các transaction, hệ thống transaction đảm bảo một đơn vị công việc sẽ
hoàn tất hoặc công việc sẽ được rollback toàn bộ. Hơn nữa transaction có thể giúp
các lập trình viên thiết kế ứng dụng chạy trong một môi trường thực thi các đơn vị
của công việc một cách nối tiếp.
3.2. Container – managed transaction
3.2.1. Khái niệm
Một trong những mục tiêu chính của kiến trúc EJB là cung cấp các dịch vụ
transaction thông qua các EJB container.
34 | T r a n g
Trong một Enterprise Java Bean với container – managed transaction, việc
bắt đầu, commit hay rollback một transaction không thông qua code của ứng dụng
mà thông qua các container được gọi là container – managed transaction.
Container bắt đầu một transaction ngay trước khi bắt đầu một EJB method và
commit transaction ngay trước khi thoát khỏi method. Mỗi method chỉ có thể
được kết hợp với một single transaction. Các multiple transaction hoặc các
transaction lồng nhau không được phép trong một method. Container – managed
transaction không yêu cầu tất cả các method đều phải kết hợp với các transaction.
Khi triển khai một bean, chúng ta xác định các method của bean kết hợp với các
transaction bằng cách thiết lập các transaction attribute trong EJB’s deployment
descriptor (trong file cấu hình) hoặc thông qua các annotation (việc xác định các
transaction metadata thông qua annotation chỉ có từ phiên bản EJB 3.0).
Để sử dụng container – managed transaction, chúng ta phải thiết lập giá trị
của (trong EJB’s deployment descriptor) hoặc
TransactionManagementType (trong annotation) là Container. Ví dụ:
deployment descriptor ejb-jar.xml:
...
Container
Annotation:
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
35 | T r a n g
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class EmployeeDetailBean implements EmployeeDetailLocal {
...
}
Tất cả các loại bean trong EJB đểu có thể sử dụng container – managed
transaction. Container – managed transaction là cách tiếp cận được ưa thích để
quản lý phạm vi transaction, nó cho phép các ứng dụng linh hoạt và di động hơn,
dễ dàng hơn trong việc phát triển, triển khai và bảo trì.
3.2.2. Transaction attribute
Trong EJB với Container – managed transaction, các transaction attribute xác
định cách các EJB container quản lý phạm vi cũng như xử lý các transaction với
mỗi lời gọi method của bean.
Đối với một bean tham gia vào Container – managed transaction, các
transaction attribute được thiết lập trong deployment descriptor hoặc annotation
của bean. Có thể thiết lập một transaction attribute cho toàn bộ bean hoặc cho
từng method. Một transaction attribute phải được xác định đối với các method
trong remote interface của một session bean và đối với các method trong home
và remote interface của một entity bean. Hành vi transaction của bean có thể được
kiểm soát bằng cách thay đổi các transaction attribute trong deployment
descriptor hoặc annotation.
Dưới đây là các transaction attribute:
- Required: Đây là attribute mặc định nếu transaction attribute không được thiết
lập trước. Method của bean sẽ luôn kết hợp với một transaction. Nếu caller
method phía client kết hợp với một transaction thì context của transaction đó
sẽ được truyền sang method của bean. Nếu method client không kết hợp với
transaction nào thì container sẽ bắt đầu một transaction mới và commit khi
method của bean return.
- RequiresNew: EJB container sẽ bắt đầu một transaction không phụ thuộc vào
việc method client có kết hợp với một transaction hay không. Nếu method
36 | T r a n g
client kết hợp với một transaction thì container sẽ tạm ngừng transaction đó
trước khi bắt đầu transaction mới. Khi method và transaction mới hoàn tất,
container sẽ trở lại transaction đã bị tạm ngừng. Attribute này thường được áp
dụng cho các method của bean nơi mà kết quả của việc gọi transaction không
phụ thuộc vào các method đó.
- Supports: transaction context sẽ được truyền từ method client sang method
của bean. Nếu method client không nằm trong một transaction context nào thì
method của bean cũng sẽ thực thi trong một bối cảnh non-transactional.
- NotSupported: khi transaction attribute này được sử dụng cho một method
của bean thì method đó không nằm trong transaction context nào. Nếu method
client nằm trong một transaction context thì container sẽ tạm ngừng
transaction đó trước khi thực thi method của bean và tiếp tục transaction khi
method này hoàn tất.
- Mandatory: khi transaction attribute này được sử dụng cho một method của
bean thì method client phải được kết hợp với một transaction, nếu không việc
gọi method của bean sẽ thất bại, ném ra một TransactionRequiredException.
- Never: transaction attribute này ít được sử dụng. Nếu attrubute này được sử
dụng cho method của bean thì method client không được kết hợp với bất kỳ
transaction nào, nếu không việc gọi method của bean sẽ thất bại, ném ra một
RemoteException.
Xét ví dụ: methodA của EJB1 gọi methodB của EJB2 như hình :
37 | T r a n g
Bảng dưới đây tóm tắt những tác động của các thuộc tính của methodB với phạm
vi của transaction. Trong bảng này, cả T1 và T2 đều là các transaction được điều
khiển bởi container. Transaction T1 được kết hợp với EJB1 còn transaction T2
được bắt đầu ngay trước khi methodB thực thi. Tùy thuộc vào các thiết lập
transaction attribute của methodB, container sẽ truyền context của phạm vi
transaction T1 hoặc bắt đầu một transaction T2 mới. Trường hợp các method
không thực thi trong transaction context nào thì kí hiệu là N/A.
Transaction attribute của
methodB
EJB1.methodA EJB2.methodB
Required
T1 T1
N/A New transaction: T2
RequiresNew
T1 New transaction: T2
N/A New transaction: T2
Supports
T1 T1
N/A N/A
NotSupported
T1 N/A
N/A N/A
Mandatory
T1 T1
N/A TransactionRequiredException
Never
T1 RemoteException
N/A N/A
Qua bảng trên có thể thấy dựa trên các thiết lập transaction attribute, EJB container
sẽ có một hành động thích hợp. Ví dụ nếu thiết lập là “Required”, EJB container
sẽ gọi thực thi methodB trong context của transaction hiện tại (T1), nhưng nếu
methodA không nằm transaction context nào thì EJB container sẽ bắt đầu một
transaction mới (T2) trước khi thực thi methodB.
3.2.3. Thiết lập transaction attribute
- Thiết lập transaction attribute cho toàn bộ EJB
Trường hợp này dùng để xác định một giá trị transaction attribute mặc định cho
tất cả các method của EJB. Thẻ được gán giá trị * (dấu sao) để
chỉ ra rằng tất cả các method đều có chung một transaction attribute.
38 | T r a n g
...
...
myEJB
*
Required
...
...
- Thiết lập transaction attribute cho một method cụ thể
Cách này được sử dụng để đề cập đến một method hoặc component interface cụ
thể của EJB.
...
...
myEJB
methodA
Supports
...
39 | T r a n g
...
3.3. Bean – managed transaction
3.3.1. Khái niệm
Container – managed transaction có nhiều ưu điểm và được sử dụng phổ biến.
tuy nhiên trong một số tình huống, Container – managed transaction là không đủ
để thực hiện quản lý và điểu khiển transaction như việc tùy biến điểm bắt đầu
transaction trong một method, khi nào commit hoặc rollback transaction. Lúc này
chúng ta có thể xem xét việc sử dụng Bean – managed transaction. Với bean –
managed transaction thì các transaction được quản lý ngay trong code của bean.
package net.javabeat.articles.ejb.txnmgmt.bean;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;
@TransactionManagement(value=TransactionManagementType.BEAN)
@Stateless
public class BillPaymentBeanBean implements BillPaymentBeanLocal {
@Resource
private UserTransaction userTransaction;
public void payBill() throws Exception{
try{
userTransaction.begin();
provideBillDetailsInfo();
identifyCustomerAccount();
makeBillPayment();
userTransaction.commit();
}catch (IncorrectBillDetailsException exception){
userTransaction.rollback();
}catch (InvalidCustomerAccountException exception){
userTransaction.rollback();
}catch (PaymentException exception){
userTransaction.rollback();
}
}
private void identifyCustomerAccount()
throws InvalidCustomerAccountException {
}
private void makeBillPayment() throws PaymentException{
40 | T r a n g
}
private void provideBillDetailsInfo()
throws IncorrectBillDetailsException{
}
}
Không như container – managed transaction, chỉ session bean và message-driven
bean mới có thể sử dụng bean – managed transaction.
3.3.2. Các method hỗ trợ
Để sử dụng Bean – managed transaction, chúng ta dùng các method của
UserTransaction interface
methods Diễn giải
void begin() Tạo một transaction mới và kết hợp nó với
thread hiện tại
void commit() Hoàn tất transaction liên quan đến thread hiện
tại.
int getStatus() Trả về trạng thái của transaction liên quan
đến thread hiện tại.
void rollback() Rollback transaction liên quan đến thread
hiện tại.
void setTransactionTimeout(int
seconds)
Thay đổi giá trị của timeout liên quan đến các
transaction bắt đầu bởi thread hiện tại với
method begin().
3.3.3. Thiết lập transaction timeout với bean – managed transaction
Transaction timeout là một cơ chế hữu ích của việc xác định một khoảng thời
gian dự kiến để thực hiện một transaction. Điều này cho phép ứng dụng tăng
cường kiểm soát và quản lý transaction. Các nhà phát triển EJB xác định timeout
cho các transaction trong EJB với BMT bằng cách gọi method
setTransactionTimeout() của UserTransaction interface. Nếu thời gian của
một transaction vượt quá giá trị timeout quy định, transaction manager sẽ rollback
transaction tự động.
41 | T r a n g
ví dụ sau thiết lập giá trị của transaction timeout là 30 giây:
// obtain user transaction context
ut = ejbContext.getUserTransaction();
// set transaction timeout before beginning a transaction
ut.setTransactionTimeout(30);
// start a transaction
ut.begin();
...
Lưu ý: timeout phải được thiết lập trước khi bắt đầu transaction. Việc thiết
lập timeout không ảnh hưởng tới transaction đã bắt đầu từ trước
3.4. Xử lý exception
3.4.1. Trường hợp EJB với bean – managed transaction
Thể hiện của bean không tự động rollback transaction của client. Client phải
chủ động bắt và đưa ra những xử lý phù hợp đối với các exception trong các khối
try – catch.
Ví dụ:
@Resource
private UserTransaction transaction;
public void someBizMethod(){
try{
transaction.begin();
}catch (NullPointerException npe){
transaction.commit();
}
}
3.4.2. Trường hợp EJB với container – managed transaction
42 | T r a n g
Khi một system exception được ném ra, container tự động rollback
transaction.
Khi một application exception được ném ra do các lỗi business logic,
container không tự động rollback transaction. EJB phải gọi method
setRollbackOnly()của EJBContext interface để thông báo cho container thực hiện
rollback transaction.
Ví dụ:
public class RegistrarEJB implements SessionBean{
SessionContext ctx;
...
public void registerForCourse(String courseID)
throws InsufficientRoomException {
try {
rs = updateCourse(courseID);
if (rs < 0) {
// Application-level exception
ctx.setRollbackOnly();
throw new InsufficientRoomException();
}
} catch (SQLException ex) {
// This is a system-level exception
throw new EJBException
("Transaction rollback due to SQLException: "+ex.getMessage());
}
}
...
}
IV. EJB Security
43 | T r a n g
4.1. Các khái niệm cơ bản
4.1.1. Tổng quan
Security là một yếu tố không thể thiếu sau khi các chức năng ứng dụng đã
hoàn tất bởi một số lý do sau đây:
Ứng dụng chúng ta đang sử dụng và triển khai là các ứng dụng dạng phân
tán, người dùng dùng web browser để truy cập ứng từ các thiết bị cá nhân đến
các server ở xa.
Việc truy cập trên đường truyền với băng thông nhỏ, số lượng người dùng
tại một lúc truy cập có rất người sử dụng dẫn đến việc truy cập chậm chạp. Chính
tốc độ chậm chạp đó dẫn đến những kẻ tấn công có thể chụp các packet truyền đi
để thay đổi thông tin hay lấy thông tin để sử dụng thông tin bất hợp lý.
Ngoài ra, thông tin sử dụng trong ứng dụng phải có sự phân biệt rõ ràng ai
được phép xem nội dung nào, sử dụng chức năng nào để đảm bảo tính bảo mật
về thông tin và không bị phá vỡ trong quá trình xử lý hay truy cập thông tin bất
hợp khác. Vấn đề này nhằm hạn chế sự sai sót trong xử lý.
4.1.2. Các cơ chế áp dụng trong Security
Có 4 cơ chế áp dụng trong Security:
- Authentication: xác thực người dùng đúng là thành viên của hệ thống thông
qua username, password (pin), vân tay,thẻ từ, …
- Authorization: những đối tượng là thành viên của hệ thống sau khi
authentication thành công sẽ được hệ thống thông qua cơ chế xác thực quyền
để cho phép họ sử dụng những chức năng và dữ liệu trong quyền hạn của họ,
không được phép thấy hay xâm phạm hay sử dụng các chức năng mà họ không
được cho phép.
44 | T r a n g
- Data Integrity: đảm bảo thông tin khi truyền đi không bị thay đổi hay truy cập
khi được truyền đi trên mạng hay trên đường truyền
- Confidentiality: Thông tin được mã hóa được truyền đi trên kênh đặc biệt (như
là SSL: Socket Secure Layer) dựa trên thông tin authentication và
authorization.
4.2. Mô hình J2EE Security
Ứng dụng J2EE được cấu tạo trên mô hình 03 lớp: Client (chứa EJB Client
truy cập middleware qua console hay thành phần Web module truy cập
middleware qua browser), Middleware – application server (chứa các Web
Container xử lý Web và EJB Container xử lý các nghiệp vụ của ứng dụng) và
CSDL (dùng để chứa và xử lý các dữ liệu).
Client truy cập vào middleware phải được xác thực để truy cập vào container
tuân theo qui luật của từng container.
45 | T r a n g
Trên middleware, các thành phần container thực hiện cơ chế xác thực để truy
cập lẫn nhau đảm bảo ứng dụng có tính bảo mật cao.
Middleware trong quá trình xử lý phải thực hiện truy cập vào CSDL với sự
xác thực của CSDL và quyền hạn thao tác trên CSDL để lấy dữ liệu về xử lý
Cơ chế bảo mật trong J2EE đảm bảo cho ứng dụng có tính bảo mật cao nhất.
Mô hình J2EE Sercurity
4.3. JAAS Framework
Java Authentication and Authorization Services (JAAS) là framework cung
cấp Authencation và Authorizaion cho các ứng dụng của Java.
Cơ chế bảo mật trong JAAS
- Xác định tài nguyên – resources cần bảo mật
- Xác định provider phù hợp cho tài nguyên cần bảo mật.
- Dùng các phương thức security của provider trên resources để thực hiện bảo
mật.
- Cung cấp các cơ chế để với client sử dụng tài nguyên đã được bảo mật.
Một số cách thức bảo mật
Basic Authentication
Client
Authorization
Databas
e
Authentication/
Authorization
Servlets
JSPs Browse
r
Web
Authentiaction
Server
Web Container
Sercurity
46 | T r a n g
- Sử dụng cơ chế người dùng muốn truy cập client phải nhập username và
password thông qua cửa số popup sercurity được hỗ trợ từ cửa sổ web
browser.
- Nếu xác thực đúng người dùng sẽ truy cập Web, ngược lại browser sẽ hiển
thị trang web không tồn tại hay không load được trang web này.
Form-based Authentication
- Tương tự như cơ chế Basic authentication nhưng developers thực hiện tạo
các form của web (html, jsp …) với các control để tiếp nhận username và
password để đón nhận giá trị nhập của người dùng và thực hiện xác thực (có
thể bằng code hay container hỗ trợ).
Digest Authentication
- Hệ thống yêu cầu thông tin xác thực
- Client cung cấp thông tin để chuyển tới server
- Server xác định thông tin, nếu đúng, sẽ tạo token chứa các thông tin mã hóa
và gửi cho client
- Client nhận được token phải dùng các cách giải mã tương ứng, nếu thực hiện
được, thông tin sẽ gửi lại server và client được phép truy cập hệ thống
- Bất kỳ giai đoạn nào có lỗi phát sinh thì việc authentication được coi là không
hiệu lực.
- Cơ chế có tính bảo mật cao vì thông tin đã được mã hóa
Certificate based Authentication
- Sử dụng dạng xác thực của một trung tâm chứng thực có uy tín để xác thực
- Dữ liệu được mã hóa và truyền đi trên kênh đặc biệt và được server xác thực,
nếu kênh này không được mở thì dữ liệu sẽ không bao giờ đến được server
- Áp dụng SSL hay HTTPS
- Các thành phần của JAAS
- Login module: thực hiện cơ chế authentication và authorization qua việc xác
thực username hay password. Đối tượng tương tác trực tiếp với client.
- Login context: client sử dụng đối tượng này để cung cấp thông tin trong quá
trình login
47 | T r a n g
- CallbackHandler và Callback:
Hỗ trợ tương tác giữa client và Login module.
Loginmodule dùng Callback để lấy thông tin của Client và
CallbackHander sẽ cung cấp các thông tin cho Loginmodule.
- Principal and Group: class để Login module chứa thông tin của
authentication (Principal) và authorization (group)
- Subject: đối tượng chứa các thông tin liên quan đến client sau khi login thành
công để sử dụng cho authentication.
- Một số đối tượng khác:
Principal: thông tin xác định đối tượng (ví dụ: username)
Credenticals: thông tin cung cấp thuộc tính liên quan đến đối tượng được
bảo mật (ví dụ: password)
Cơ chế thực hiện Authentication: client truy cập resource bảo mật trên Server
có các bước xử lý như sau:
- Client gửi các thông tin có liên quan đến việc login đến CallbackHandler (ví
dụ: username, password) để thực hiện khởi tạo và lưu trữ giá trị để sử dụng
trong các bước tiếp theo.
- CallbackHandler đưa thông tin đến Login Context để khởi tạo cho quá trình
thực hiện authentication
- Login Context thực hiện tạo instance LoginModule, thông báo cho Login
Context và Login Context đưa đối tượng cho Client (tương tự như cơ chế
client truy cập EJB thông quan EJBObject)
- Client gọi phương thức Login trên đối tượng Login Module
- Login module yêu cầu thông tin xác thực từ CallbackHandle để lấy thông tin
mà client đã cung cấp trong quá trình khởi tạo.
- Login module thực hiện xử lý xác thực. Nếu xác thực sai, sẽ đưa ra exception
còn đúng sẽ thông báo cho user.
- Việc xác thực thành công, thông tin của client sẽ được lưu trữ trong đối tượng
Subject thông qua Login Context.
48 | T r a n g
Cơ chế thực hiện authorization: Client hay user truy cập các phương thức trên
Server. Thông tin của user trong Subject được cung cấp để xác định role tương
ứng. Nếu không được truy cập sẽ thông báo lỗi, ngược lại gọi phương thức thực
thi
Có 02 cách thức để thực hiện authorization:
Declarative:
- Không cần lập trình mà chỉ mô tả thông tin qua deployment descriptor.
- Deployment descriptor mô tả và thông báo cho container các roles về security
và security constraints để client truy cập các phương thức phải tuân theo qui
tắc bảo mật. Đặc biệt container sẽ hỗ trợ cơ chế security cho các ứng dụng
được deploy vào container
- Cấu hình security cho ứng dụng EJB deploy trên server Jboss.
Programmatic:
- Lập trình bảo mật trực tiếp trong Bean
- Các phương thức xử lý business sẽ được tích hợp với các kiểm tra bảo mật
- Có khả năng kết hợp với declarative để tăng tính uyển chuyển trong việc vận
dụng bảo mật
Việc xác thực và phân quyền của JAAS trên mô hình J2EE/JavaEE được
container kiểm tra trên ACL – Access Control List
49 | T r a n g
- ACL là một tập tin tài nguyên chứa đựng thông tin liên quan đến quyền xác
thực và nhóm user được phân quyền
- Khi có một request gửi đến server thì lời yêu cầu bắt buộc được container
kiểm tra trên ACL, nếu như tồn tại thành viên sẽ tiếp tục kiểm tra quyền để
thành viên được cấp quyền truy cập tài nguyên hay bị từ chối không có phép
truy cập
4.4. Security trên EJB
Login module trong JBoss được thể hiện qua security domain với JNDI có cú
pháp java:/jaas/. JBoss đã hỗ trợ sẵn một domain mặc định là others
JBoss cung cấp UserRolesLoginModule nhằm lấy username, password và role từ
tập tin ACL, cụ thể ACL được thể hiện qua các tập tin properties trong ejb package
users.properties: Chứa các username và password theo từng hàng một với dạng
username=password (lưu ý: không có khoảng cách trong các thành phần khai báo)
Ví dụ: users.properties
admin=123456
guest=123456
roles.properties: Chứa nội dung phân quyền cho các user, thông tin được lưu trữ
thành từng hàng có dạng username=roles[, role2][,…][, rolen] (lưu ý: tên username
phải tồn tại trong tập tin users.property và các role có thể có nhiều hơn 1 và cách
nhau bằng dấu phẩy).
Ví dụ: roles.properties
admin=admin,manager
guest=user
50 | T r a n g
Các bước xây dựng ứng dụng EJB có áp dụng Security
Bước 1: Tạo đối tượng ứng dụng hỗ trợ EJB
Bước 2: cấu hình LoginModule với các file properties đặt tại thư mục của application
users.properties
roles.properties
Bước 3: bổ sung cấu hình security các tập tin deployment descriptor các thành phần
element hỗ trợ khai báo security.
Bổ sung việc xác định domain trong tập tin jboss.xml
java:/jaas/tên domain
....
Bổ sung các thành phần resource, phương thực cần hỗ trợ security trong tập tin ejb-
jar.xml
....
tên role trong file roles</security-
role>
các security role khác
tên role trong file roles
tên ejb
tên method
loại dữ liệu
…
51 | T r a n g
Cấu hình nhiều hơn một phương thức, để cấu hình toàn bộ phương thức dùng
dấu *
...
Bước 4: xây dựng client truy cập vào ứng dụng thông qua các xác thực
Đối với ứng dụng web – bổ sung cấu ứng authentication và authorization trên tập tin
web.xml
(xác định tài nguyên được security)
tên resource
/* hay tên tài nguyên/thư mục
HEAD (xác định các phương thức HTTP được
security)
GET
PUT
POST
DELETE
(xác định các roles được phép truy cập tài nguyên)
tên role – tồn tại trong file roles
các role khác
(xác định cơ chế mã hóa dữ liệu để truyền đi)
NONE|INTEGRITY|CONFIDENTIAL</transport-
guarantee> (NONE: không mã hóa; INTEGRITY: mã hóa; CONFIDENTIAL: mã hóa và
truyền kênh riêng)
(xác định cơ chế authentication)
BASIC|FORM|DIGEST
(xác định các roles được security để truy cập ứng dụng)
tên role
52 | T r a n g
các security role khác
Bước 5: Đóng gói ứng dụng, deploy và testing ứng dụng
Một số thông tin hay phương thức hỗ trợ xử lý security trong Bean của EJB
EJB Context là gateway đến container và có khả năng truy cập từ bên trong bean. Do
vậy, các phương thức callbacks hoạt động trên EJB Context để tương tác với container
một cách dễ dàng.
EJB Context sử dụng javax.ejb.EJBContext với các chức năng hỗ trợ
Methods Mô tả
getHome() Sử dụng để lấy đối tượng Home Object.
getCallerPrincipal()
Sử dụng để lấy định danh bảo mật của client đang truy
cập vào hệ thống để có thể xác định vai trò của client
trong việc truy cập các chức năng của EJB
isCallerInRole(String role) Xác định client có được phân quyền – role hay không
setRollbackOnly()
Thiết lập chế độ rollback trong transaction hiện hành
cho instance bean
getRollbackOnly()
Xác định xem transaction có được đánh dấu rollback
không
getUserTransaction() Lập trình để thực hiện điều khiển transaction
Session – Entity Context Interface được extends từ EJBContext, do vậy, session bean có
thể truy cập tất cả các phương thức của EJBContext.
V. Tài liệu tham khảo
1)
2)
3)
4)
5)
6)
7) sách Manning - EJB 3 in Action, Debu Panda - Reza Rahman - Derek Lane
Các file đính kèm theo tài liệu này:
- bao_cao_ejb_6063.pdf