Bài viết này đi kèm với tài nguyên chất lượng cao, nhấn vào để nhận
Giới thiệu: J2EE là nền tảng then chốt cung cấp các chuẩn và API phát triển ứng dụng doanh nghiệp. Bộ tài nguyên này tích hợp các tệp JAR và tập tin cấu hình liên quan đến các framework phổ biến như Hibernate, Mybatis, Spring, Struts và JSON. Các framework này cung cấp các giải pháp doanh nghiệp thông qua các tệp JAR cốt lõi và tập tin cấu hình của chúng, bao gồm thao tác cơ sở dữ liệu, truy vấn SQL, tiêm phụ thuộc, quản lý giao dịch và phát triển ứng dụng web. Việc nắm vững cách sử dụng và cấu hình các framework này là yếu tố then chốt giúp nâng cao hiệu suất phát triển và khả năng bảo trì dự án.
- Tổng quan nền tảng J2EE và tầm quan trọng của framework
Trong lĩnh vực công nghệ thông tin hiện đại, Java 2 Platform, Enterprise Edition (J2EE), nay gọi là Jakarta EE, là nền tảng mạnh mẽ dành riêng cho phát triển ứng dụng doanh nghiệp. Nền tảng J2EE cung cấp một bộ quy chuẩn hoàn chỉnh, định nghĩa các API Java và môi trường chạy để xây dựng các ứng dụng đa lớp dựa trên thành phần. Các ứng dụng này có thể triển khai trong môi trường mạng phân tán, hỗ trợ nhiều loại khách hàng.
1.1 Kiến trúc cơ bản của nền tảng J2EE
Kiến trúc cơ bản của nền tảng J2EE bao gồm một số thành phần chính như: thành phần web, Java Beans doanh nghiệp (EJB) và thành phần ứng dụng khách. Thành phần web xử lý yêu cầu người dùng và tạo nội dung động; EJB đóng gói logic nghiệp vụ của ứng dụng doanh nghiệp; thành phần ứng dụng khách cung cấp giao diện người dùng phong phú. Các thành phần này được quản lý thông qua các container, container cung cấp nhiều dịch vụ như quản lý giao dịch, bảo mật và kiểm soát truy cập tài nguyên.
1.2 Vai trò của framework trong hệ sinh thái J2EE
Framework đóng vai trò cực kỳ quan trọng trong hệ sinh thái J2EE. Chúng cung cấp cho lập trình viên cách tiếp cận có cấu trúc và mô-đun hơn khi xây dựng và quản lý ứng dụng. Framework không chỉ cung cấp mô hình lập trình và API mà còn bao gồm các quy ước và thực hành tốt nhất, giúp lập trình viên tránh sai lầm, đồng thời tăng hiệu suất phát triển và khả năng bảo trì ứng dụng. Các framework J2EE phổ biến bao gồm Hibernate, Mybatis, Spring, v.v., chúng hỗ trợ lập trình viên giải quyết các vấn đề phức tạp một cách đơn giản hơn.
- Framework Hibernate và tập tin cấu hình
2.1 Tổng quan framework Hibernate
2.1.1 Thành phần cốt lõi của Hibernate
Hibernate là framework ánh xạ quan hệ đối tượng (Object-Relational Mapping, ORM) mạnh mẽ, đóng vai trò cầu nối giữa các đối tượng Java và bảng cơ sở dữ liệu trong nền tảng J2EE. Thành phần cốt lõi của Hibernate chủ yếu bao gồm:
- Session: Đại diện cho một tương tác ngắn hạn giữa ứng dụng và cơ sở dữ liệu. Nó chịu trách nhiệm các thao tác bền vững, bao gồm lưu trữ, truy xuất, cập nhật và xóa dữ liệu.
- SessionFactory: Là đối tượng an toàn với luồng và nặng, dùng để tạo các phiên làm việc Session. Thường chỉ cần tạo một instance SessionFactory cho mỗi ứng dụng.
- Transaction: Là luồng công việc đại diện cho việc truy cập và có thể sửa đổi dữ liệu trong cơ sở dữ liệu.
- Configuration: Dùng để cấu hình Hibernate, tải tập tin
hibernate.cfg.xmlkhi khởi động. - Query: Cung cấp API để truy xuất dữ liệu.
- Criteria: Một cách khác để thực hiện truy vấn động, so với Query, Criteria cung cấp kiểm tra kiểu tại thời điểm biên dịch.
- Mapping Metadata: Định nghĩa mối quan hệ ánh xạ giữa đối tượng và bảng cơ sở dữ liệu.
2.1.2 Nguyên lý hoạt động của Hibernate
Cơ chế hoạt động của Hibernate được thực hiện bằng cách đọc tập tin cấu hình và tập tin ánh xạ, thiết lập mối quan hệ giữa đối tượng Java và bảng cơ sở dữ liệu. Khi thực hiện thao tác lưu trữ dữ liệu, Hibernate sẽ tạo ra câu lệnh SQL tương ứng để gửi đến cơ sở dữ liệu. Quy trình hoạt động như sau:
- Ứng dụng bắt đầu thao tác cơ sở dữ liệu thông qua đối tượng Session.
- Session sử dụng cơ chế quản lý giao dịch để đảm bảo tính nguyên tử của thao tác dữ liệu.
- Khi cần lưu trữ đối tượng Java, Hibernate chuyển đổi trạng thái đối tượng thành câu lệnh SQL tương ứng.
- Câu lệnh SQL được thực thi thông qua kết nối cơ sở dữ liệu.
- Sau khi thao tác hoàn tất, Session cập nhật trạng thái bền vững của đối tượng Java dựa trên phản hồi.
- Khi giao dịch được cam kết, tất cả dữ liệu đã thay đổi sẽ được lưu trữ trong cơ sở dữ liệu.
2.2 Phân tích chi tiết tập tin cấu hình Hibernate
2.2.1 Giải thích chi tiết tập tin hibernate.cfg.xml
hibernate.cfg.xml là tập tin cấu hình quan trọng trong framework Hibernate, dùng để cấu hình các thuộc tính kết nối, tập tin ánh xạ và một số thuộc tính toàn cục. Tập tin cấu hình có thể chứa các phần chính sau:
- Thẻ
<property>: Xác định thuộc tính Hibernate, như kết nối cơ sở dữ liệu, phương ngôn, loại giao dịch, v.v. - Thẻ
<mapping>: Chỉ định vị trí tập tin ánh xạ, có thể là tập tin XML hoặc chú thích. - Thẻ
<class>: Trong phiên bản Hibernate cũ, dùng để ánh xạ một lớp thực thể đến một bảng cơ sở dữ liệu.
Cấu trúc điển hình của tập tin hibernate.cfg.xml như sau:
<hibernate-configuration>
<session-factory>
<!-- Cấu hình kết nối cơ sở dữ liệu -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/mydb</property>
<property name="connection.username">user</property>
<property name="connection.password">pass</property>
<!-- Phương ngôn SQL -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Kích hoạt quản lý ngữ cảnh phiên làm việc tự động của Hibernate -->
<property name="current_session_context_class">thread</property>
<!-- In tất cả câu SQL đã thực thi ra stdout -->
<property name="show_sql">true</property>
<!-- Xóa và tạo lại lược đồ cơ sở dữ liệu khi khởi động -->
<property name="hbm2ddl.auto">update</property>
<!-- Tập tin ánh xạ -->
<mapping class="com.example.MyClass" />
</session-factory>
</hibernate-configuration>
2.2.2 Cấu hình và tối ưu hóa SessionFactory
SessionFactory là một trong những đối tượng quan trọng nhất trong Hibernate, tiêu tốn nhiều bộ nhớ và tài nguyên, vì vậy cấu hình và tối ưu hóa nó rất quan trọng. Cấu hình SessionFactory thường liên quan đến các yếu tố sau:
- Cấu hình pool kết nối: Để cải thiện tái sử dụng và hiệu suất kết nối cơ sở dữ liệu, thường cần cấu hình pool kết nối, ví dụ như sử dụng thuộc tính
connection.pool_sizeđể đặt kích thước pool. - Kiểm soát giao dịch: Thông qua cấu hình nhà máy giao dịch và mức cách ly, có thể kiểm soát độ đồng thời và tính bền vững của giao dịch.
- Cấu hình cache cấp hai: SessionFactory có thể cấu hình cache cấp hai, sử dụng bộ nhớ đệm để lưu dữ liệu truy vấn thường xuyên, tăng hiệu suất.
<property name="connection.pool_size">10</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
2.2.3 Chiến lược tối ưu hóa hiệu suất SessionFactory
Để tối ưu hóa hiệu suất SessionFactory hơn nữa, lập trình viên có thể cân nhắc các chiến lược sau:
- Chiến lược cache hợp lý: Cấu hình kích thước cache cấp một và cấp hai phù hợp theo tình huống, tránh tràn bộ nhớ.
- Tối ưu hóa lazy loading: Sử dụng đúng cách tính năng lazy loading để tránh tạo quá nhiều câu SQL.
- Tối ưu hóa truy vấn: Sử dụng HQL hoặc Criteria API để xây dựng câu truy vấn hiệu quả, tránh vấn đề truy vấn N+1.
2.3 Áp dụng thực tế Hibernate
2.3.1 Ánh xạ thực thể và thao tác lưu trữ dữ liệu
Ánh xạ thực thể là quá trình ánh xạ đối tượng Java đến bảng cơ sở dữ liệu. Trong Hibernate, có thể hoàn thành cấu hình ánh xạ bằng tập tin XML hoặc chú thích. Dưới đây là một ví dụ đơn giản sử dụng chú thích để ánh xạ thực thể:
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "birth_date")
private Date birthDate;
// Bỏ qua phương thức getter và setter...
}
Thao tác lưu trữ dữ liệu bao gồm lưu đối tượng vào cơ sở dữ liệu, cập nhật, xóa và truy vấn. Ví dụ, mã lưu đối tượng Employee vào cơ sở dữ liệu như sau:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Employee newEmployee = new Employee("John", "Doe", new Date());
session.save(newEmployee);
tx.commit();
session.close();
2.3.2 Quản lý phiên làm việc và sử dụng cache trong Hibernate
Quản lý phiên làm việc là đơn vị cơ bản của thao tác bền vững. Một phiên làm việc có thể thực hiện nhiều thao tác cơ sở dữ liệu trong suốt vòng đời. Việc quản lý phiên làm việc quan trọng là kiểm soát giao dịch. Ví dụ, mã mở, cam kết và rollback giao dịch như sau:
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
// Thao tác bền vững
session.save(employee);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
session.close();
}
Hibernate cung cấp cache cấp một và cache cấp hai để cải thiện hiệu suất. Cache cấp một là ở cấp phiên làm việc, được làm sạch sau mỗi giao dịch; cache cấp hai là ở cấp SessionFactory, có thể chia sẻ giữa nhiều phiên làm việc. Ví dụ sử dụng cache:
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
Properties properties = new Properties();
// Cấu hình cache cấp hai
properties.put("cache.provider_class", "org.hibernate.cache.EhCacheProvider");
configuration.setProperties(properties);
Mã trên minh họa cách cấu hình Hibernate sử dụng EhCache làm nhà cung cấp cache cấp hai. Cách tiếp cận này có thể nâng cao hiệu suất thao tác của Hibernate.
Đến đây, chúng ta đã tìm hiểu toàn diện các thành phần cốt lõi, nguyên lý hoạt động và phân tích chi tiết tập tin cấu hình của framework Hibernate trong chương hai, và minh họa qua các ứng dụng thực tế như ánh xạ thực thể, thao tác lưu trữ dữ liệu cũng như quản lý phiên làm việc và sử dụng cache. Với kiến thức nền tảng này, lập trình viên có thể tiếp tục khám phá các tính năng nâng cao và kỹ thuật tối ưu của Hibernate để xây dựng các lớp lưu trữ dữ liệu hiệu quả và ổn định.
- Framework Mybatis và tập tin cấu hình
3.1 Nguyên lý và tính năng của framework Mybatis
3.1.1 Giới thiệu thành phần cốt lõi của Mybatis
Mybatis là framework lớp lưu trữ bán tự động, cung cấp một cách thực hiện ánh xạ quan hệ đối tượng (ORM) tuyệt vời, giúp đơn giản hóa tương tác giữa ứng dụng Java và cơ sở dữ liệu. Mybatis sử dụng XML đơn giản hoặc chú thích để cấu hình và ánh xạ thông tin gốc, ánh xạ các interface và các POJOs (Plain Old Java Objects) sang các bản ghi trong cơ sở dữ liệu.
Thành phần cốt lõi của Mybatis gồm các phần sau:
- SqlSessionFactory: Là đơn vị làm việc chính của Mybatis, dùng để tạo SqlSession. SqlSessionFactory thường là một interface thực hiện, ví dụ như DefaultSqlSessionFactory, sử dụng tập tin cấu hình hoặc lớp cấu hình để tạo các instance SqlSession.
- SqlSession: Đại diện cho phiên làm việc với cơ sở dữ liệu, các thao tác cơ sở dữ liệu thực tế đều được thực hiện thông qua SqlSession. SqlSession cung cấp các phương thức khác nhau để thực thi các câu lệnh SQL đã ánh xạ và trả về các đối tượng thực thể được ánh xạ.
- Executor: Là bộ thực thi khi Mybatis thực thi SQL, chịu trách nhiệm tạo câu lệnh SQL và duy trì cache truy vấn.
- MappedStatement: Chứa toàn bộ thông tin của một câu lệnh ánh xạ SQL, như câu lệnh SQL, thông tin tham số đầu vào và kết quả đầu ra được ánh xạ.
Mybatis thông qua các thành phần này liên kết các đối tượng trong ứng dụng với dữ liệu trong cơ sở dữ liệu, đơn giản hóa mã nguồn lớp truy cập dữ liệu, giúp lập trình viên tập trung vào việc thực hiện logic nghiệp vụ.
3.1.2 So sánh Mybatis với các framework ORM truyền thống
So với các framework ORM truyền thống, Mybatis có một số đặc điểm nổi bật:
- Tính linh hoạt cao: Mybatis không hoàn toàn đối tượng như Hibernate, cho phép lập trình viên viết câu lệnh SQL gốc, làm cho hỗ trợ truy vấn phức tạp trở nên linh hoạt hơn.
- Nhẹ nhàng: Mybatis không có quản lý vòng đời đối tượng đầy đủ, vì vậy nhẹ hơn các framework ORM khác.
- Tính tùy chỉnh cao: Lập trình viên có thể tự do định nghĩa tập tin ánh xạ, kiểm soát tốt hơn việc thực thi SQL, đồng thời có thể viết các thủ tục lưu trữ phức tạp.
- Hiệu suất ưu việt: Do có thể viết SQL gốc, tối ưu kế hoạch thực thi SQL, cũng như hỗ trợ cache cấp một và cấp hai, Mybatis thể hiện hiệu suất vượt trội.
Tuy nhiên, sự linh hoạt và tính tùy chỉnh này cũng có nghĩa là lập trình viên phải viết thêm nhiều mã để quản lý các thao tác lớp lưu trữ dữ liệu, điều này có thể làm tăng độ phức tạp so với các framework ORM toàn đối tượng.
3.2 Phân tích chi tiết tập tin cấu hình Mybatis
3.2.1 Phân tích tập tin cấu hình toàn cục Mybatis
Tập tin cấu hình toàn cục của Mybatis (thường có tên mybatis-config.xml) chứa các cấu hình cơ bản khi Mybatis chạy và thông tin chi tiết kết nối cơ sở dữ liệu. Tập tin này là tùy chọn, nhưng việc sử dụng nó giúp kiểm soát hành vi của Mybatis tốt hơn.
Các thành phần chính của tập tin cấu hình toàn cục bao gồm:
- properties: Định nghĩa các thuộc tính cần thiết để kết nối cơ sở dữ liệu, như driver, URL, tên người dùng và mật khẩu.
- settings: Dùng để điều chỉnh hành vi chạy thời gian thực của Mybatis, như lazy loading, cache toàn cục, thực hiện nhật ký, v.v.
- typeAliases: Cung cấp bí danh cho các kiểu tự định nghĩa, giúp đơn giản hóa tên lớp Java.
- typeHandlers: Dùng để xác định cách chuyển đổi giữa kiểu Java và kiểu JDBC.
- objectFactory: Phụ trách tạo các đối tượng kết quả.
- plugins: Dùng để viết plugin, can thiệp và tùy chỉnh hành vi cốt lõi của Mybatis.
- environments: Cấu hình môi trường chạy của Mybatis, ví dụ như nguồn dữ liệu và trình quản lý giao dịch.
- databaseIdProvider: Cung cấp định danh nhà sản xuất cơ sở dữ liệu, Mybatis có thể thực thi các câu lệnh SQL khác nhau tùy theo nhà sản xuất cơ sở dữ liệu.
- mappers: Dùng để đăng ký các tập tin ánh xạ hoặc lớp ánh xạ, tức là các tập tin XML hoặc interface định nghĩa câu lệnh SQL và ánh xạ kết quả.
Dưới đây là một ví dụ đơn giản của tập tin cấu hình toàn cục Mybatis:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<properties resource="db.properties"/>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.example.model"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.example.mapper"/>
</mappers>
</configuration>
Tập tin cấu hình này xác định các thông số cơ bản của môi trường chạy Mybatis, cách kết nối cơ sở dữ liệu và đăng ký ánh xạ.
3.2.2 Vai trò và phương pháp cấu hình tập tin ánh xạ
Tập tin ánh xạ là một trong những thành phần quan trọng nhất trong framework Mybatis, là tập tin XML dùng để định nghĩa câu lệnh SQL và ánh xạ với interface. Mỗi tập tin ánh xạ thường tương ứng với một interface, Mybatis sẽ tự động tìm câu lệnh SQL được định nghĩa trong tập tin ánh xạ dựa trên tên phương thức và tham số của interface để thực thi.
Cấu trúc đơn giản của tập tin ánh xạ Mybatis như sau:
<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUser" parameterType="int" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
Trong ví dụ này, thuộc tính namespace định nghĩa tên đầy đủ của interface tương ứng với tập tin ánh xạ, thẻ select định nghĩa một thao tác truy vấn, thuộc tính id tương ứng với tên phương thức trong interface, parameterType chỉ định kiểu tham số phương thức, resultType chỉ định kiểu kết quả trả về.
Vai trò và phương pháp cấu hình tập tin ánh xạ của Mybatis cụ thể bao gồm:
- Định nghĩa câu lệnh SQL: Trực tiếp viết câu lệnh SQL trong tập tin ánh xạ, giúp tùy chỉnh SQL cho các cơ sở dữ liệu khác nhau, tận dụng chức năng đặc thù của cơ sở dữ liệu.
- Hỗ trợ SQL động: Mybatis hỗ trợ SQL động, thông qua các thẻ như
<if>,<choose>,<foreach>,<sql>, có thể ghép nối các đoạn SQL khác nhau dựa trên điều kiện để thực hiện logic truy vấn phức tạp. - Xử lý tham số: Trong tập tin ánh xạ có thể sử dụng các cách khác nhau để xử lý tham số SQL, ví dụ như sử dụng
#{}và${}để phân biệt tham số precompiled và thay thế chuỗi trực tiếp. - Ánh xạ kết quả: Thông qua thẻ
<resultMap>có thể định nghĩa quy tắc ánh xạ phức tạp hơn, thực hiện ánh xạ cấu trúc dữ liệu phức tạp, như truy vấn liên kết, ánh xạ kết quả lồng nhau, v.v.
Cấu hình tập tin ánh xạ không chỉ nâng cao hiệu suất thao tác cơ sở dữ liệu mà còn thông qua việc tách biệt câu lệnh SQL khỏi logic nghiệp vụ, giúp nâng cao khả năng bảo trì và dễ đọc của mã nguồn. Thông qua cấu hình và sử dụng hợp lý tập tin ánh xạ, có thể nâng cao hiệu suất và trải nghiệm lập trình của ứng dụng.
- Framework Spring và tập tin cấu hình
4.1 Khái niệm cốt lõi của framework Spring
4.1.1 Hai đặc tính cốt lõi của Spring: IoC và AOP
Lý do framework Spring chiếm vị trí quan trọng trong phát triển ứng dụng doanh nghiệp Java là do nó cung cấp hai khái niệm cốt lõi: đảo ngược kiểm soát (Inversion of Control, IoC) và lập trình hướng khía cạnh (Aspect-Oriented Programming, AOP). IoC là linh hồn của framework Spring, thông qua container quản lý việc tạo và mối quan hệ phụ thuộc của đối tượng, đạt được tính lỏng lẻo, nâng cao khả năng tái sử dụng và bảo trì của các thành phần hệ thống. AOP bổ sung cho lập trình hướng đối tượng, cho phép lập trình viên định nghĩa mã xử lý các vấn đề chéo (cross-cutting concerns) như nhật ký, quản lý giao dịch, v.v., mã này có thể độc lập với logic nghiệp vụ, thực hiện thông qua các khía cạnh.
4.1.2 Tổng quan kiến trúc module của Spring
Framework Spring được chia thành nhiều module theo chức năng, bao gồm container cốt lõi, truy cập/lắp ghép dữ liệu, web, AOP, tin nhắn và test. Module container cốt lõi cung cấp container IoC, là nền tảng cho tất cả các module khác. Module truy cập/lắp ghép dữ liệu hỗ trợ trừu tượng và lắp ghép các công nghệ truy cập dữ liệu như JDBC, JPA, JMS, v.v. Module web cung cấp nền tảng để xây dựng ứng dụng web, bao gồm hỗ trợ tích hợp với Struts. Module AOP cung cấp thực hiện AOP và quản lý giao dịch chung. Module tin nhắn dựa trên trừu tượng nguồn tin nhắn của Spring. Module test hỗ trợ kiểm thử sử dụng JUnit và TestNG.
4.2 Khám phá sâu tập tin cấu hình Spring
4.2.1 Cấu trúc và phân tích các mục cấu hình của tập tin cấu hình Spring
Tập tin cấu hình của Spring thường là tập tin XML, định nghĩa thông tin cấu hình Bean, mối quan hệ phụ thuộc và các thuộc tính liên quan. Phần tử gốc của tập tin là <configuration>, các phần tử con thường là <bean>, dùng để định nghĩa một Bean. Mỗi phần tử <bean> có thuộc tính id và class, lần lượt biểu thị định danh duy nhất và lớp Java tương ứng. Có thể đặt thêm các thuộc tính khác như scope (phạm vi), init-method (phương thức khởi tạo), destroy-method (phương thức hủy bỏ). Ngoài ra, có thể sử dụng phần tử <property> để tiêm phụ thuộc, <constructor-arg> dùng để tiêm qua constructor. Phần tử <import> dùng để nhập các tập tin cấu hình khác.
4.2.2 Phạm vi Bean và quản lý vòng đời
Spring hỗ trợ nhiều phạm vi Bean, bao gồm singleton (mặc định, đơn thể), prototype (mỗi yêu cầu tạo instance mới), request (mỗi yêu cầu HTTP tạo một instance), session (mỗi session HTTP tạo một instance), global session (tạo instance trong session HTTP toàn cục, thường dùng trong môi trường Portlet). Vòng đời của Bean gồm hai quá trình: khởi tạo và hủy bỏ. Quá trình khởi tạo có thể cấu hình thông qua thuộc tính init-method hoặc sử dụng chú thích @PostConstruct để chỉ định phương thức khởi tạo, quá trình hủy bỏ có thể cấu hình thông qua thuộc tính destroy-method hoặc sử dụng chú thích @PreDestroy để chỉ định phương thức hủy bỏ.
4.3 Ứng dụng thực tế Spring
4.3.1 Tích hợp Spring vào ứng dụng web
Trong ứng dụng web, tích hợp Spring thường yêu cầu cấu hình ContextLoaderListener và DispatcherServlet trong web.xml. ContextLoaderListener dùng để tải tập tin cấu hình ngữ cảnh ứng dụng, còn DispatcherServlet chịu trách nhiệm xử lý yêu cầu từ phía frontend. Spring cung cấp nhiều lớp điều khiển như @Controller, @RestController, chúng có thể xử lý yêu cầu HTTP và trả về phản hồi. Spring cũng hỗ trợ nhiều trình phân giải view, ví dụ InternalResourceViewResolver, có thể phân giải tên view logic thành tài nguyên view thực tế.
4.3.2 Quản lý giao dịch và cấu hình bảo mật Spring
Spring cung cấp quản lý giao dịch khai báo, giúp đơn giản hóa việc xử lý giao dịch. Lập trình viên có thể sử dụng chú thích @Transactional để khai báo ranh giới giao dịch, cũng có thể cấu hình thông qua tập tin XML. Spring Security là framework lựa chọn để bảo vệ ứng dụng, cung cấp thực hiện xác thực và ủy quyền. Có thể cấu hình kho người dùng, bộ mã hóa mật khẩu và quy trình đăng nhập. Thông qua cấu hình phần tử http, có thể định nghĩa quy tắc truy cập cho các mẫu URL, kết hợp với người dùng, vai trò để kiểm soát quyền truy cập.
- Framework Struts và tập tin cấu hình
5.1 Nguyên lý và thành phần của framework Struts
5.1.1 Luồng làm việc và thành phần cốt lõi của Struts
Framework Struts được thiết kế theo mô hình MVC (Model-View-Controller), rộng rãi sử dụng để xây dựng ứng dụng web Java EE. Luồng làm việc của Struts bắt đầu từ yêu cầu người dùng, yêu cầu này được nhận bởi ActionServlet của Struts, một Servlet đặc biệt xử lý yêu cầu HTTP. Sau đó, dựa trên URL yêu cầu, ActionServlet chuyển tiếp yêu cầu đến lớp Action tương ứng, Action xử lý logic nghiệp vụ và trả về đối tượng ActionForward, đối tượng này chỉ rõ view (trang JSP hoặc tài nguyên khác) sẽ chuyển tiếp đến sau khi xử lý yêu cầu.
Thành phần cốt lõi của Struts bao gồm:
- ActionServlet (controller): Phụ trách nhận yêu cầu từ client (thường là trình duyệt web), sau đó gọi đối tượng
Actiontương ứng để xử lý yêu cầu. - Action class (một phần controller): Dùng để thực hiện logic nghiệp vụ, và trả về đối tượng
ActionForwarddựa trên kết quả thực thi. - ActionForm (một phần model): Là đối tượng bao bọc dữ liệu, dùng để nhận và lưu trữ dữ liệu yêu cầu của người dùng.
- Tập tin cấu hình (
struts-config.xml): Dùng để định nghĩa thông tin cấu hình của tất cả các thành phần trong ứng dụng Struts, bao gồm Action, ActionForm, ActionForward, v.v. - Tập tin tài nguyên quốc tế hóa: Dùng để hỗ trợ môi trường đa ngôn ngữ, cung cấp tài nguyên thông báo phiên bản ngôn ngữ khác nhau.
Struts thông qua các thành phần này tách logic nghiệp vụ khỏi hiển thị trang, nâng cao đáng kể khả năng bảo trì và mở rộng của ứng dụng web.
5.1.2 Triển khai mô hình MVC trong Struts
Struts thực hiện mô hình MVC thông qua hỗ trợ ở cấp framework, tách logic nghiệp vụ, mô hình dữ liệu và giao diện người dùng của ứng dụng web. Dưới đây là các bước chi tiết để thực hiện mô hình MVC trong framework Struts:
- Giao diện người dùng (View): Được định nghĩa trong trang JSP, thông qua biểu mẫu HTML thu thập dữ liệu đầu vào của người dùng. Struts cung cấp một thư viện thẻ, giúp dễ dàng tham chiếu đến thành phần ActionForm trong trang JSP, cũng như thực hiện ràng buộc dữ liệu và xác thực.
- Controller (Controller): Được thực hiện bởi
ActionServlet. Nó phụ trách gọi các thành phần logic nghiệp vụ (thường là lớp Action), và quyết định view tiếp theo (View) dựa trên đối tượngActionForwardtrả về. - Logic nghiệp vụ (Model): Được thực hiện bởi lớp Action, phụ trách xử lý dữ liệu từ ActionForm và thực hiện logic nghiệp vụ tương ứng. Kết quả thường được lưu trữ trong đối tượng ActionForm để phản hồi cho người dùng.
Nhờ sự tách biệt này, Struts giúp lập trình viên dễ dàng bảo trì và quản lý ứng dụng web. Đồng thời, các tính năng như tập tin cấu hình Struts và interceptor tùy chỉnh cung cấp tính linh hoạt đủ để lập trình viên tùy chỉnh hành vi theo nhu cầu.
5.2 Phân tích chi tiết tập tin cấu hình Struts
5.2.1 Phân tích tập tin cấu hình struts.xml
Tập tin cấu hình struts.xml của Struts là trái tim của toàn bộ ứng dụng Struts, định nghĩa tất cả các Action, ActionForm, ActionForward và interceptor. Tập tin này sử dụng định dạng XML, cho phép lập trình viên định nghĩa cách Struts phản hồi các yêu cầu người dùng cụ thể.
Một tập tin cấu hình struts.xml cơ bản thường chứa các phần sau:
<?xml version="1.0" encoding="UTF-8" ?>
<struts>
<constant name="struts.i18n.encoding" value="UTF-8" />
<package name="default" extends="struts-default" namespace="/">
<!-- Cấu hình Action -->
<action name="loginForm" class="com.example.LoginAction" method="execute">
<result name="success">/success.jsp</result>
<result name="input">/login.jsp</result>
</action>
<!-- Cấu hình Action khác... -->
</package>
</struts>
Trong cấu hình trên:
- Phần tử
<struts>chứa toàn bộ cấu hình Struts. - Phần tử
<constant>dùng để cấu hình các hằng số được sử dụng bên trong Struts. - Phần tử
<package>dùng để tổ chức các Action liên quan, có thuộc tínhname,extendsvànamespace. Thuộc tínhextendschỉ rõ package này kế thừa từ package nào (thường làstruts-default). - Phần tử
<action>định nghĩa một Action, thuộc tínhnamechỉ định tên yêu cầu của người dùng, thuộc tínhclasschỉ định lớp Action thực hiện yêu cầu, thuộc tínhmethodchỉ định phương thức xử lý. - Phần tử
<result>định nghĩa phản hồi sau khi Action thực thi, thuộc tínhnamechỉ định tên kết quả (ví dụ "success" hoặc "input"), thuộc tínhlocationchỉ định tài nguyên view trả về cho client.
5.2.2 Cấu hình interceptor tùy chỉnh và kiểu kết quả
Interceptor là một tính năng mạnh mẽ của Struts 2, cho phép lập trình viên chèn hành vi tùy chỉnh trước và sau khi Action thực thi. Interceptor tùy chỉnh cần thực hiện interface Interceptor và đăng ký trong tập tin cấu hình. Dưới đây là một ví dụ đơn giản về interceptor tùy chỉnh:
package com.example.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
public void destroy() {}
public void init() {}
public String intercept(ActionInvocation invocation) throws Exception {
// Logic tùy chỉnh, ví dụ ghi nhật ký
return invocation.invoke(); // Tiếp tục quy trình sau
}
}
Đăng ký interceptor này trong struts.xml:
<interceptors>
<interceptor name="myInterceptor" class="com.example.interceptor.MyInterceptor" />
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<action name="login" class="com.example.LoginAction">
<interceptor-ref name="myStack" />
<result name="success">/success.jsp</result>
<result name="input">/login.jsp</result>
</action>
Trong ví dụ này, interceptor tùy chỉnh myInterceptor được thêm vào stack interceptor myStack, sau đó stack này được áp dụng cho Action login.
Cấu hình kiểu kết quả cho phép lập trình viên định nghĩa kiểu kết quả tùy chỉnh, ví dụ như sau khi người dùng đăng nhập thành công, có thể trực tiếp chuyển hướng đến một URL khác:
<result-types>
<result-type name="redirect" class="com.opensymphony.xwork2.ActionContextRedirectResult" />
</result-types>
Sau đó, trong Action sử dụng kiểu kết quả tùy chỉnh này:
<action name="login" class="com.example.LoginAction">
<result name="success" type="redirect">/dashboard.jsp</result>
</action>
Điều này khiến khi Action đăng nhập thực thi thành công, người dùng sẽ được chuyển hướng đến trang /dashboard.jsp.
5.3 Thực hành các tính năng nâng cao Struts
5.3.1 Xác thực biểu mẫu và hỗ trợ quốc tế hóa
Xác thực biểu mẫu
Struts hỗ trợ xác thực biểu mẫu ở cấp Action, kết quả xác thực thường được trả về giao diện người dùng để hiển thị lỗi người dùng nhập. Dưới đây là một ví dụ lớp Action có logic xác thực biểu mẫu:
package com.example.action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.*;
public class LoginAction extends ActionSupport {
private String username;
private String password;
@RequiredFieldValidator(message="Tên người dùng không được để trống")
public void setUsername(String username) {
this.username = username;
}
@RequiredFieldValidator(message="Mật khẩu không được để trống")
@StringLengthFieldValidator(minLength=6, maxLength=20, message="Độ dài mật khẩu phải từ 6 đến 20 ký tự")
public void setPassword(String password) {
this.password = password;
}
public String execute() {
// Thực hiện logic đăng nhập...
return SUCCESS;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
Trong mã trên, các chú thích @RequiredFieldValidator và @StringLengthFieldValidator dùng để xác thực trường username và password. Nếu xác thực thất bại, Struts sẽ tự động thêm thông báo lỗi vào Action.errors và chuyển hướng người dùng về trang nhập liệu.
Hỗ trợ quốc tế hóa
Struts hỗ trợ quốc tế hóa thông qua các tập tin tài nguyên. Lập trình viên có thể chuẩn bị các tập tin tài nguyên khác nhau cho các môi trường ngôn ngữ khác nhau, ví dụ ApplicationResources.properties và ApplicationResources_fr.properties dùng cho môi trường tiếng Anh và tiếng Pháp. Trong các tập tin này, có thể định nghĩa cặp khóa-giá trị để xuất văn bản các ngôn ngữ khác nhau.
Các tập tin tài nguyên có thể được tham chiếu trong Action, trang JSP và tập tin cấu hình. Ví dụ, trong lớp con của ActionSupport, có thể sử dụng phương thức getText() để lấy văn bản từ tập tin tài nguyên:
public String execute() {
String welcomeMessage = getText("welcome.message");
// Sử dụng welcomeMessage cho các bước tiếp theo...
return SUCCESS;
}
Để thực hiện quốc tế hóa, cần cấu hình trong tập tin struts.xml để chỉ định đường dẫn tập tin tài nguyên và gói tài nguyên được tải.
5.3.2 Tải lên/xuất file và xử lý ngoại lệ
Tải lên file
Struts 2 cung cấp cơ chế tải lên file đơn giản, bật bằng cách thiết lập hằng số struts.multipart.enabled thành true. Lập trình viên có thể sử dụng interceptor FileUploadInterceptor và chú thích @Action trong lớp Action để xử lý yêu cầu tải lên file.
Dưới đây là một ví dụ đơn giản tải lên file:
package com.example.action;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.UploadException;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public class FileUploadAction extends ActionSupport {
private List<FileItem> uploadFileList;
public void parse() throws Exception {
if (ServletFileUpload.isMultipartContent(request)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
uploadFileList = upload.parseRequest(request);
// Xử lý logic tải lên file...
} catch (UploadException e) {
addActionError(e.getMessage());
}
}
}
// Phương thức getter và setter...
}
Trong mã trên, phương thức parse() dùng để phân tích file tải lên. Bộ sưu tập uploadFileList chứa các đối tượng FileItem lưu trữ thông tin liên quan đến file tải lên.
Xuất file
Xuất file có thể thực hiện thông qua phương thức execute() của Action trả về StreamResult. Lập trình viên cần tạo một lớp Action chứa phương thức chuẩn bị dữ liệu luồng để tải xuống. Sau đó trong struts.xml cấu hình phần tử result tương ứng, sử dụng kiểu stream:
<action name="downloadFile" class="com.example.action.DownloadAction">
<result type="stream">
<param name="inputName">inputStream</param>
<param name="contentType">application/octet-stream</param>
<param name="contentDisposition">attachment; filename="example.txt"</param>
</result>
</action>
Trong lớp DownloadAction:
public class DownloadAction extends ActionSupport {
private InputStream inputStream;
public String execute() {
// Chuẩn bị luồng file...
return SUCCESS;
}
public InputStream getInputStream() {
return inputStream;
}
}
Xử lý ngoại lệ
Trong Struts 2, xử lý ngoại lệ có thể thực hiện thông qua interceptor và kiểu kết quả. Ví dụ, có thể tạo interceptor xử lý ngoại lệ, khi bắt được ngoại lệ, chuyển hướng yêu cầu đến trang lỗi:
public class ExceptionInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
try {
return invocation.invoke();
} catch (Exception e) {
// Ghi log thông tin ngoại lệ...
return ERROR;
}
}
}
Trong struts.xml cấu hình interceptor này và thêm vào một stack interceptor:
<interceptors>
<interceptor name="exceptionInterceptor" class="com.example.interceptor.ExceptionInterceptor" />
<!-- Cấu hình các interceptor khác... -->
</interceptors>
<action name="someAction" class="com.example.action.SomeAction">
<interceptor-ref name="exceptionInterceptor" />
<!-- Áp dụng các interceptor khác... -->
<result name="success">/somePage.jsp</result>
<result name="error">/error.jsp</result>
</action>
Trong cấu hình trên, nếu SomeAction ném ra ngoại lệ trong quá trình thực thi, interceptor exceptionInterceptor sẽ bắt nó và chuyển hướng người dùng đến trang error.jsp.
Thông qua các tính năng nâng cao này, có thể tăng cường đáng kể chức năng và trải nghiệm người dùng của ứng dụng web. Trong thực tế phát triển, dựa trên nhu cầu và độ phức tạp cụ thể của dự án, lập trình viên có thể lựa chọn linh hoạt các công nghệ và chiến lược phù hợp để xây dựng các ứng dụng mạnh mẽ và dễ bảo trì hơn.
- Xử lý JSON và các tệp JAR liên quan
JSON (JavaScript Object Notation) là định dạng trao đổi dữ liệu nhẹ, dễ đọc và viết cho con người, cũng dễ phân tích và tạo ra cho máy tính. Nó dựa trên một tập con của JavaScript, nhưng không bị giới hạn bởi ngôn ngữ, được sử dụng rộng rãi trong nhiều ngôn ngữ lập trình.
6.1 Công nghệ JSON và bối cảnh ứng dụng
6.1.1 Khái niệm cơ bản của định dạng dữ liệu JSON
Định dạng dữ liệu JSON chủ yếu gồm hai phần: đối tượng và mảng. Đối tượng là tập hợp các "cặp khóa-giá trị" vô thứ tự, tương tự Map trong Java; mảng là tập hợp các giá trị có thứ tự, tương tự List trong Java. Mỗi giá trị có thể là kiểu dữ liệu đơn giản như chuỗi, số, boolean, hoặc kiểu dữ liệu phức hợp như đối tượng hoặc mảng.
6.1.2 Vai trò của JSON trong phát triển web
Trong phát triển web, JSON thường được sử dụng như định dạng trao đổi dữ liệu giữa frontend và backend. Nhờ tính nhẹ nhàng, việc truyền dữ liệu trở nên hiệu quả hơn. Backend có thể trả dữ liệu dưới dạng JSON cho frontend, frontend sau đó hiển thị dữ liệu JSON đã nhận lên trang. Ngược lại, người dùng cũng có thể gửi yêu cầu dữ liệu dưới dạng JSON đến backend.
6.2 Phân tích các tệp JAR xử lý JSON phổ biến
6.2.1 So sánh Gson, Jackson và Fastjson
Trong thế giới Java, có nhiều tệp JAR xử lý dữ liệu JSON như Gson, Jackson và Fastjson. Dưới đây là so sánh chính giữa ba thư viện này:
- Gson: Là thư viện do Google cung cấp, có thể chuyển đổi giữa đối tượng Java và chuỗi JSON. Ưu điểm của Gson là dễ sử dụng, không cần cấu hình phức tạp để bắt đầu. Tuy nhiên, nó không tối ưu về hiệu suất, đặc biệt khi xử lý các tài liệu JSON lớn.
- Jackson: Là thư viện xử lý JSON mạnh mẽ, tích hợp tốt với framework Spring. Jackson có hiệu suất và tính linh hoạt xuất sắc, hỗ trợ tạo và phân tích JSON, cũng như binding dữ liệu. Trong các dự án lớn, Jackson thường được chọn là thư viện JSON ưu tiên.
- Fastjson: Là thư viện xử lý JSON từ Alibaba, đặc điểm là tốc độ nhanh và kích thước nhỏ. Nó cung cấp cách đơn giản hơn để chuyển đổi giữa đối tượng Java và chuỗi JSON. Tuy nhiên, Fastjson có thể kém hơn hai thư viện kia trong xử lý cấu trúc dữ liệu phức tạp và đảm bảo an toàn kiểu.
6.2.2 Tích hợp và sử dụng các tệp JAR trong các framework khác nhau
Các thư viện xử lý JSON khác nhau có thể tích hợp vào các framework khác nhau. Ví dụ, trong framework Spring, có thể dễ dàng tích hợp các thư viện JSON này thông qua việc tiêm. Sau khi tích hợp, lập trình viên có thể sử dụng chú thích @ResponseBody trong controller để trả về trực tiếp một đối tượng Java, Spring sẽ tự động sử dụng thư viện JSON đã tích hợp để chuyển đổi đối tượng thành chuỗi JSON.
Dưới đây là một ví dụ controller Spring MVC đơn giản, minh họa cách sử dụng thư viện Jackson để xử lý JSON:
@RestController
public class JsonController {
@GetMapping("/user")
public User getUser() {
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setEmail("john@example.com");
return user;
}
}
Trong ví dụ này, khi client gọi giao diện /user, Spring sẽ sử dụng Jackson để tự động tuần tự hóa đối tượng User thành chuỗi JSON và trả về cho client.
6.3 Trường hợp thực tế xử lý dữ liệu JSON
6.3.1 Tương tác dữ liệu JSON trong dịch vụ RESTful
Dịch vụ RESTful thường sử dụng các phương thức HTTP (GET, POST, PUT, DELETE) để thực hiện thao tác trên tài nguyên. Trong các thao tác này, JSON được sử dụng rộng rãi như định dạng trao đổi dữ liệu. Dưới đây là một ứng dụng Spring Boot đơn giản, thực hiện một dịch vụ RESTful để lấy và cập nhật thông tin người dùng:
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable("id") Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable("id") Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
return ResponseEntity.ok(user);
}
}
Trong ví dụ này, chú thích @GetMapping và @PutMapping xử lý yêu cầu lấy và cập nhật người dùng. Chú thích @RequestBody dùng để ràng buộc dữ liệu JSON gửi từ client vào đối tượng User.
6.3.2 Bảo mật và tối ưu hiệu suất dữ liệu JSON
Dữ liệu JSON trong quá trình truyền và lưu trữ cũng cần xem xét vấn đề bảo mật. Một thực hành phổ biến là sử dụng chữ ký số hoặc thuật toán mã hóa để bảo vệ tính toàn vẹn và bí mật của dữ liệu. Ngoài ra, khi xử lý lượng lớn dữ liệu JSON, tối ưu hiệu suất cũng rất quan trọng. Có thể thực hiện thông qua các cách sau:
- Sử dụng thư viện JSON hiệu suất cao: Ví dụ như cấu hình
ObjectMappercủa Jackson để tăng hiệu suất tuần tự hóa và phân tích. - Giảm lượng dữ liệu truyền mạng: Thông qua nén dữ liệu JSON (ví dụ như sử dụng gzip) để giảm lượng dữ liệu truyền, hoặc giảm các trường dữ liệu trả về nếu không ảnh hưởng logic nghiệp vụ.
- Cache: Đối với dữ liệu không thay đổi thường xuyên, có thể sử dụng cơ chế cache để giảm số lần truy vấn cơ sở dữ liệu, từ đó nâng cao hiệu suất tổng thể.
Thông qua các phương pháp này, có thể tăng tốc độ xử lý dữ liệu JSON và khả năng phản hồi của hệ thống mà vẫn đảm bảo an toàn dữ liệu.
Bài viết này đi kèm với tài nguyên chất lượng cao, nhấn vào để nhận
Giới thiệu: J2EE là nền tảng then chốt cung cấp các chuẩn và API phát triển ứng dụng doanh nghiệp. Bộ tài nguyên này tích hợp các tệp JAR và tập tin cấu hình liên quan đến các framework phổ biến như Hibernate, Mybatis, Spring, Struts và JSON. Các framework này cung cấp các giải pháp doanh nghiệp thông qua các tệp JAR cốt lõi và tập tin cấu hình của chúng, bao gồm thao tác cơ sở dữ liệu, truy vấn SQL, tiêm phụ thuộc, quản lý giao dịch và phát triển ứng dụng web. Việc nắm vững cách sử dụng và cấu hình các framework này là yếu tố then chốt giúp nâng cao hiệu suất phát triển và khả năng bảo trì dự án.
Bài viết này đi kèm với tài nguyên chất lượng cao, nhấn vào để nhận