Spring MVC và JSP: Tạo Giao Diện Động Trên Lộ Trình Java Spring

Chào mừng trở lại với chuỗi bài viết “Lộ Trình Java Spring”! Trên hành trình khám phá framework mạnh mẽ này, chúng ta đã đi qua những khái niệm cốt lõi như tại sao chọn Spring, kiến trúc Spring, Dependency Injection (DI), Inversion of Control (IoC), Annotations, và làm quen với Spring MVC – trái tim của việc xây dựng ứng dụng web trong Spring. Chúng ta cũng đã tìm hiểu Servlet là gì, nền tảng mà Spring MVC dựa trên.

Tuy nhiên, một ứng dụng web không chỉ có backend xử lý logic. Nó cần một giao diện để người dùng tương tác, một nơi để hiển thị dữ liệu. Trong các bài viết trước về Spring MVC, chúng ta tập trung vào Controller và cách xử lý request. Bài viết hôm nay sẽ đào sâu vào khía cạnh “View” của mô hình Model-View-Controller, cụ thể là cách sử dụng JSP (JavaServer Pages) để tạo ra các trang web động trong dự án Spring MVC của bạn. Dù thế giới web hiện đại có nhiều lựa chọn khác, JSP vẫn là một công nghệ quan trọng cần biết, đặc biệt khi làm việc với các dự án truyền thống hoặc hiểu sâu hơn về cách Spring MVC hoạt động với các công nghệ view.

JSP là Gì và Tại Sao Nó Phù Hợp Với Spring MVC?

JSP, viết tắt của JavaServer Pages, là một công nghệ cho phép các nhà phát triển tạo ra nội dung web động và tương tác. Về bản chất, một tệp JSP trông giống như một trang HTML thông thường, nhưng nó chứa các đoạn code Java (được gọi là scriplet), thẻ đặc biệt của JSP, hoặc Thẻ Biểu thức (Expression Language – EL). Khi một request đến một trang JSP, máy chủ web (như Tomcat nhúng trong Spring Boot) sẽ biên dịch trang JSP đó thành một Java Servlet. Servlet này sau đó sẽ được thực thi, tạo ra nội dung HTML, và nội dung này sẽ được gửi về trình duyệt của người dùng.

Mối quan hệ giữa JSP và Servlets rất chặt chẽ: JSP là một cách viết Servlet dễ dàng hơn, tập trung vào phần trình bày (presentation). Thay vì phải viết toàn bộ HTML trong code Java của Servlet (điều rất bất tiện), bạn có thể viết HTML gần như bình thường và chỉ nhúng code Java hoặc các thẻ đặc biệt khi cần hiển thị dữ liệu động hoặc thực hiện logic trình bày đơn giản.

Trong mô hình Spring MVC, Controller xử lý yêu cầu, tương tác với Service/Model để lấy dữ liệu, và sau đó trả về một tên “logical view name” (tên logic của view) cùng với dữ liệu cần hiển thị (thường thông qua đối tượng Model hoặc ModelAndView). Nhiệm vụ của Spring MVC là tìm kiếm View phù hợp với tên logic đó và “render” (kết xuất) nó, sử dụng dữ liệu được truyền từ Controller.

Đây chính là lúc JSP phát huy vai trò. Spring MVC sử dụng một thành phần gọi là View Resolver. Khi Controller trả về tên view (ví dụ: “home”, “productList”), View Resolver sẽ nhận tên này và xác định vị trí vật lý của tệp view (ví dụ: `/WEB-INF/jsp/home.jsp`). Sau đó, Spring MVC sẽ chuyển dữ liệu từ Model tới View này để View có thể hiển thị nội dung động. JSP, với khả năng nhúng dữ liệu từ Model thông qua EL và JSTL (JSP Standard Tag Library), là một lựa chọn View phổ biến và hiệu quả cho kiến trúc này.

Thiết Lập Dự Án Spring MVC Sử Dụng JSP

Để sử dụng JSP trong dự án Spring MVC (dù là Spring Boot hay Spring truyền thống), bạn cần thêm các dependency cần thiết vào tệp cấu hình build của mình (như Maven hoặc Gradle) và cấu hình Spring MVC để tìm kiếm và xử lý các tệp JSP.

Thêm Dependencies

Bạn cần ít nhất hai dependencies chính:

  • Servlet API: Mặc dù bạn đang dùng Spring, ứng dụng web của bạn vẫn chạy trên nền tảng Servlet.
  • JSP API và JSTL: Thư viện cần thiết để phân tích cú pháp JSP và cung cấp các thẻ tiêu chuẩn (JSTL) giúp làm việc với dữ liệu động dễ dàng hơn.

Nếu bạn đang sử dụng Maven, thêm các dependency sau vào tệp pom.xml:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version> <!-- Hoặc phiên bản mới hơn -->
    <scope>provided</scope> <!-- Scope 'provided' vì máy chủ ứng dụng sẽ cung cấp nó -->
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version> <!-- Hoặc phiên bản mới hơn -->
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version> <!-- Phiên bản JSTL phổ biến -->
</dependency>

Nếu bạn đang sử dụng Gradle:

providedCompile 'javax.servlet:javax.servlet-api:4.0.1' // Hoặc phiên bản mới hơn
providedCompile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3' // Hoặc phiên bản mới hơn
implementation 'javax.servlet:jstl:1.2'

Lưu ý cho Spring Boot: Nếu bạn dùng Spring Boot và muốn chạy ứng dụng dưới dạng file WAR hoặc chạy nhúng (embedded) với Tomcat/Jetty, bạn có thể cần thêm dependency của máy chủ nhúng kèm theo khả năng xử lý JSP. Ví dụ, với Tomcat:

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope> <!-- Thường là provided nếu build WAR -->
    <!-- Nếu chạy nhúng và muốn JSP hoạt động ngay cả khi đóng gói JAR,
         bỏ 'provided' scope hoặc cấu hình lại.
         Spring Boot DevTools thường tự thêm nếu có web starter và jasper.
     -->
</dependency>

tomcat-embed-jasper chứa JSTL và hỗ trợ biên dịch JSP khi chạy nhúng.

Cấu Hình View Resolver

Bước quan trọng tiếp theo là nói cho Spring MVC biết nơi tìm các tệp JSP và cách ánh xạ tên view logic sang đường dẫn vật lý của tệp JSP. Chúng ta làm điều này bằng cách cấu hình một ViewResolver, cụ thể là InternalResourceViewResolver.

Sử dụng Java Config (phổ biến trong Spring hiện đại và Spring Boot):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc // Chỉ định đây là cấu hình MVC
// Trong Spring Boot với @SpringBootApplication, không cần @EnableWebMvc trừ khi muốn tùy chỉnh sâu
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setViewClass(JstlView.class); // Quan trọng để JSTL hoạt động tốt
        resolver.setPrefix("/WEB-INF/jsp/"); // Thư mục chứa các tệp JSP
        resolver.setSuffix(".jsp");      // Hậu tố của tệp view
        return resolver;
    }

    // Cần thêm cấu hình ResourceHandler nếu muốn phục vụ tài nguyên tĩnh (CSS, JS, images)
    // @Override
    // public void addResourceHandlers(ResourceHandlerRegistry registry) {
    //     registry.addResourceHandler("/static/**")
    //             .addResourceLocations("/static/");
    // }
}

Giải thích cấu hình:

  • @Configuration: Đánh dấu lớp này chứa các định nghĩa bean. (Liên kết đến: Tất Tần Tật Về Spring Annotations)
  • @EnableWebMvc: Bật cấu hình mặc định cho Spring MVC. (Trong Spring Boot, @SpringBootApplication thường làm điều này tự động qua Autoconfiguration nếu bạn thêm spring-boot-starter-web).
  • @Bean: Đăng ký InternalResourceViewResolver như một bean trong Spring IoC container. (Liên kết đến: Spring IoC trong Thực Tế)
  • InternalResourceViewResolver: Một View Resolver đơn giản, chuyển đổi tên view logic thành đường dẫn trực tiếp đến tài nguyên (trong trường hợp này là tệp JSP) trong ứng dụng web.
  • setViewClass(JstlView.class): Đảm bảo rằng Spring sẽ sử dụng JstlView để render các tệp JSP. Điều này cần thiết để JSTL hoạt động đúng.
  • setPrefix("/WEB-INF/jsp/"): Đây là tiền tố sẽ được thêm vào tên view logic. Thư mục /WEB-INF/ là một thư mục đặc biệt trong ứng dụng web Java, nội dung bên trong nó không thể truy cập trực tiếp từ trình duyệt, đảm bảo các tệp JSP của bạn chỉ có thể được truy cập thông qua Controller.
  • setSuffix(".jsp"): Hậu tố sẽ được thêm vào tên view logic.

Ví dụ: Nếu Controller trả về tên view là “welcome”, InternalResourceViewResolver với cấu hình trên sẽ tìm tệp tại đường dẫn /WEB-INF/jsp/welcome.jsp.

Sử dụng XML Config (phổ biến trong Spring truyền thống):

<!-- Đảm bảo namespace 'mvc' và 'context' được khai báo trong thẻ <beans> -->
<!-- <beans ... xmlns:mvc="http://www.springframework.org/schema/mvc"> -->

<mvc:annotation-driven /> <!-- Tương đương @EnableWebMvc -->
<context:component-scan base-package="com.yourpackage" /> <!-- Quét các @Controller, @Service, ... -->

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

<!-- Cần thêm cấu hình resource mapping nếu dùng XML -->
<!-- <mvc:resources mapping="/static/**" location="/static/" /> -->

Cấu hình này tương đương với Java Config ở trên nhưng sử dụng cú pháp XML. (Liên kết đến: Làm Chủ Cấu Hình Với XML và Annotations)

Cấu Trúc Thư Mục

Theo cấu hình trên, bạn cần tạo một thư mục có tên WEB-INF bên trong thư mục webapp (hoặc src/main/webapp) của dự án. Bên trong WEB-INF, tạo một thư mục khác tên là jsp. Tất cả các tệp JSP của bạn sẽ nằm trong thư mục jsp này.

your-project/
├── src/
│   └── main/
│       ├── java/     <-- Code Java (Controllers, Services, etc.)
│       └── webapp/
│           ├── WEB-INF/
│           │   └── jsp/  <-- Nơi chứa các tệp .jsp
│           │       ├── home.jsp
│           │       └── productList.jsp
│           └── static/ <-- Tài nguyên tĩnh (CSS, JS, hình ảnh)
│               ├── css/
│               └── js/
├── pom.xml (hoặc build.gradle)
└── ...

Tạo JSP Đơn Giản và Hiển Thị Dữ Liệu Từ Controller

Bây giờ, hãy tạo một tệp JSP đơn giản và xem cách nó nhận và hiển thị dữ liệu từ Controller.

Bước 1: Viết Controller

Tạo một Controller đơn giản trả về tên view và thêm dữ liệu vào Model.

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class MyWebController {

    @GetMapping("/greeting")
    public String showGreeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
        // Thêm một thuộc tính vào Model
        model.addAttribute("userName", name);
        model.addAttribute("message", "Chào mừng bạn đến với trang JSP!");

        // Trả về tên view logic. View Resolver sẽ tìm /WEB-INF/jsp/greeting.jsp
        return "greeting";
    }
}

Trong Controller này:

  • @GetMapping("/greeting"): Ánh xạ request GET đến “/greeting” tới phương thức này.
  • @RequestParam(...) String name: Lấy giá trị của parameter “name” từ request (nếu có), mặc định là “World” nếu không tồn tại.
  • Model model: Spring MVC tự động cung cấp đối tượng Model. Bạn dùng nó để mang dữ liệu từ Controller sang View.
  • model.addAttribute("userName", name): Thêm một thuộc tính có tên “userName” với giá trị là biến name vào Model.
  • return "greeting": Trả về tên view logic là “greeting”.

Bước 2: Tạo tệp JSP tương ứng

Trong thư mục /WEB-INF/jsp/, tạo tệp greeting.jsp.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Trang Chào Hỏi</title>
</head>
<body>
    <h1>Hello, ${userName}!</h1>
    <p>${message}</p>

    <a href="/">Quay lại trang chủ</a>
</body>
</html>

Trong tệp JSP này:

  • <%@ page ... %>: Chỉ thị trang JSP, thiết lập ngôn ngữ (Java), loại nội dung (HTML), và mã hóa ký tự.
  • ${userName}: Đây là cú pháp của Expression Language (EL). Nó sẽ lấy giá trị của thuộc tính “userName” từ Model (mà Controller đã đặt) và hiển thị ở đây. Tương tự với ${message}. EL giúp truy cập dữ liệu từ Model cực kỳ đơn giản.

Khi bạn chạy ứng dụng và truy cập /greeting (hoặc /greeting?name=Alice), Spring MVC sẽ gọi Controller, Controller thêm dữ liệu vào Model và trả về “greeting”. View Resolver tìm /WEB-INF/jsp/greeting.jsp, Spring chuyển Model sang cho JSP. JSP được biên dịch và thực thi, sử dụng EL để điền dữ liệu vào các chỗ tương ứng, tạo ra HTML cuối cùng và gửi về trình duyệt.

Sử Dụng JSTL Để Thêm Logic Trình Bày

Mặc dù EL rất tiện lợi để hiển thị dữ liệu, đôi khi bạn cần logic phức tạp hơn trong View, ví dụ như lặp qua một danh sách, hiển thị nội dung có điều kiện, hoặc định dạng dữ liệu. Đây là lúc JSP Standard Tag Library (JSTL) trở nên hữu ích.

JSTL cung cấp một bộ các thẻ (tags) chuẩn để thực hiện các tác vụ phổ biến mà không cần nhúng nhiều code Java (scriplet) trực tiếp vào JSP (điều này thường bị coi là một practice tồi vì làm giảm tính dễ đọc và bảo trì của code view). Các thẻ JSTL được chia thành nhiều nhóm (core, fmt, sql, xml), trong đó nhóm “core” là phổ biến nhất.

Để sử dụng JSTL trong tệp JSP, bạn cần khai báo nó ở đầu trang bằng chỉ thị <%@ taglib ... %>.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!-- Khai báo JSTL Core -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <!-- Khai báo JSTL Formatting (định dạng ngày, số...) -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Danh Sách Sản Phẩm</title>
</head>
<body>
    <h1>Danh Sách Sản Phẩm</h1>

    <!-- Sử dụng thẻ <c:if> cho điều kiện -->
    <c:if test="${empty products}">
        <p>Không có sản phẩm nào trong danh sách.</p>
    </c:if>

    <!-- Sử dụng thẻ <c:forEach> để lặp qua danh sách -->
    <c:if test="${not empty products}">
        <ul>
            <c:forEach var="product" items="${products}"> <!-- lặp qua collection 'products' trong Model -->
                <li>
                    <strong><c:out value="${product.name}" /></strong> <!-- <c:out> giúp thoát ký tự đặc biệt (XSS) -->
                    - Giá: <fmt:formatNumber value="${product.price}" type="currency" currencyCode="VND" />
                </li>
            </c:forEach>
        </ul>
    </c:if>

    <!-- Có thể sử dụng các biến tạm với <c:set> -->
    <c:set var="totalItems" value="${products.size()}" />
    <p>Tổng số sản phẩm: ${totalItems}</p>

</body>
</html>
</pre>

<p>Để ví dụ trên hoạt động, Controller cần đặt một danh sách các đối tượng Product vào Model:</p>
<pre><code class="language-java">import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;

@Controller
public class ProductController {

    // Giả định có một lớp Product đơn giản
    public static class Product {
        private String name;
        private double price;

        // Constructor, getters, setters...
        public Product(String name, double price) { this.name = name; this.price = price; }
        public String getName() { return name; }
        public double getPrice() { return price; }
    }

    @GetMapping("/products")
    public String listProducts(Model model) {
        List<Product> productList = Arrays.asList(
            new Product("Laptop", 25000000),
            new Product("Mouse", 500000),
            new Product("Keyboard", 1500000)
        );
        model.addAttribute("products", productList);

        // Trả về tên view logic "productList"
        return "productList"; // Maps to /WEB-INF/jsp/productList.jsp
    }
}

Trong ví dụ này, chúng ta đã sử dụng các thẻ JSTL Core như <c:if><c:forEach> để kiểm tra xem danh sách sản phẩm có rỗng không và lặp qua nó. Thẻ <c:out> được dùng để hiển thị giá trị một cách an toàn, tự động thoát các ký tự đặc biệt (phòng chống tấn công XSS đơn giản). Thẻ <fmt:formatNumber> từ thư viện JSTL Formatting giúp định dạng giá tiền.

Xử Lý Form Với JSP và Spring MVC

JSP cũng rất hữu ích để tạo các form HTML và gửi dữ liệu về Controller.

Bước 1: Tạo form trong JSP

Tạo một tệp JSP (ví dụ: inputForm.jsp) chứa form:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Nhập Thông Tin</title>
</head>
<body>
    <h1>Nhập Tên Của Bạn</h1>

    <form action="/processForm" method="post"> <!-- 'action' là URL Controller sẽ xử lý, 'method' là phương thức HTTP -->
        <label for="userName">Tên:</label>
        <input type="text" id="userName" name="userName"><br><br>

        <input type="submit" value="Gửi">
    </form>

    <c:if test="${not empty message}"> <!-- Hiển thị thông báo nếu có từ Controller -->
        <p style="color: green;">${message}</p>
    </c:if>

</body>
</html>

Form này sẽ gửi dữ liệu bằng phương thức POST đến URL `/processForm`. Tên của input (name="userName") là quan trọng, vì nó sẽ được dùng để nhận dữ liệu ở phía Controller.

Bước 2: Viết Controller xử lý form

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class FormController {

    @GetMapping("/showForm")
    public String showFormPage() {
        // Trả về tên view logic "inputForm" để hiển thị form
        return "inputForm"; // Maps to /WEB-INF/jsp/inputForm.jsp
    }

    @PostMapping("/processForm")
    public String processForm(@RequestParam("userName") String name, Model model) {
        // Xử lý dữ liệu nhận được
        String resultMessage = "Xin chào, " + name + "!";

        // Thêm kết quả vào Model để hiển thị lại trên trang form (hoặc trang khác)
        model.addAttribute("message", resultMessage);

        // Có thể redirect đến trang khác hoặc trả về lại trang form ban đầu với thông báo
        return "inputForm"; // Hoặc "redirect:/successPage"
    }
}

Trong Controller này:

  • @GetMapping("/showForm"): Hiển thị trang form ban đầu khi người dùng truy cập /showForm.
  • @PostMapping("/processForm"): Xử lý request POST từ form.
  • @RequestParam("userName") String name: Lấy giá trị của input có tên “userName” từ request parameter và gán vào biến name.
  • Sau khi xử lý, Controller thêm thông báo vào Model và trả về lại view “inputForm”. Trang JSP sẽ hiển thị thông báo nhờ thẻ <c:if> kiểm tra sự tồn tại của message trong Model.

Tóm Tắt Cấu Hình InternalResourceViewResolver

Đây là bảng tóm tắt các thuộc tính chính của InternalResourceViewResolver khi làm việc với JSP:

Thuộc tính (Property) Mô tả Giá trị thường dùng cho JSP Ý nghĩa
prefix Đường dẫn thư mục tiền tố cho các tệp view. /WEB-INF/jsp/ Chỉ định vị trí các tệp JSP trong thư mục WEB-INF.
suffix Hậu tố của tệp view. .jsp Chỉ định loại tệp view cần tìm.
viewClass Lớp View được sử dụng để render các resource. org.springframework.web.servlet.view.JstlView Đảm bảo JSTL được xử lý đúng khi render JSP.
order (Không bắt buộc) Thứ tự của View Resolver nếu có nhiều loại. Số nguyên dương (ví dụ: 1, 2…) Xác định View Resolver nào được thử trước. Mặc định thường là 0 hoặc theo thứ tự đăng ký bean.

Ưu Điểm và Hạn Chế Của JSP Trong Spring MVC

Ưu điểm:

  • Đơn giản cho các ứng dụng truyền thống: Dễ dàng tạo các trang HTML động dựa trên dữ liệu từ server.
  • Tích hợp tốt với Spring MVC: Mô hình View Resolver của Spring MVC hoạt động rất hiệu quả với JSP.
  • Có JSTL: Cung cấp các thẻ giúp thực hiện logic trình bày phổ biến mà không cần nhúng code Java phức tạp.
  • Server-side rendering: Nội dung được tạo ra hoàn toàn ở server, thân thiện với SEO (Search Engine Optimization).

Hạn chế:

  • Ít linh hoạt cho các ứng dụng hiện đại: Không phù hợp với kiến trúc REST API + Single Page Application (SPA) hoặc Mobile Application.
  • Tách biệt không hoàn hảo: Mặc dù JSTL và EL giúp giảm thiểu, việc nhúng logic trình bày vào tệp HTML vẫn có thể khiến code trở nên khó đọc và bảo trì nếu không cẩn thận.
  • Performance: Việc biên dịch JSP thành Servlet có thể gây độ trễ nhỏ trong lần truy cập đầu tiên (mặc dù thường được cache sau đó).
  • Frontend phức tạp: Xây dựng giao diện người dùng phong phú, tương tác cao chỉ với JSP/JSTL có thể rất khó khăn so với các framework frontend hiện đại như React, Angular, Vue.
  • Security (XSS): Cần cẩn thận sử dụng <c:out> hoặc các biện pháp thoát ký tự khác để tránh lỗ hổng Cross-Site Scripting nếu hiển thị dữ liệu từ input của người dùng.

JSP trong Bối Cảnh Hiện Đại

Trong bối cảnh phát triển web hiện đại, JSP không còn là lựa chọn mặc định cho các ứng dụng web mới. Xu hướng hiện nay là xây dựng backend như các Microservices hoặc API (thường trả về dữ liệu dưới dạng JSON/XML) và sử dụng các framework JavaScript phía frontend (SPA) hoặc các framework server-side rendering hiện đại hơn (như Thymeleaf, Freemarker) để tạo giao diện. Spring Boot và Spring Cloud hỗ trợ rất tốt cho các kiến trúc này.

Tuy nhiên, JSP vẫn còn được sử dụng rộng rãi trong các hệ thống legacy, các ứng dụng nội bộ đơn giản không cần giao diện quá phức tạp, hoặc khi bạn cần duy trì và phát triển tiếp một ứng dụng đã có sẵn sử dụng JSP. Việc hiểu cách JSP hoạt động với Spring MVC là một kỹ năng giá trị, giúp bạn làm việc hiệu quả với nhiều loại dự án khác nhau trên Lộ trình Spring Boot nói riêng và Java Spring Roadmap nói chung.

Kết Luận

Trong bài viết này, chúng ta đã tìm hiểu cách tích hợp và sử dụng tệp JSP trong dự án Spring MVC. Chúng ta đã xem xét cách thêm dependency, cấu hình InternalResourceViewResolver, tạo tệp JSP đơn giản, truyền dữ liệu từ Controller bằng Model và sử dụng Expression Language. Ngoài ra, chúng ta cũng đã khám phá sức mạnh của JSTL trong việc thêm logic trình bày vào JSP và cách xử lý form cơ bản.

Hiểu về JSP và cách nó hoạt động trong Spring MVC không chỉ giúp bạn xây dựng các ứng dụng web truyền thống mà còn củng cố kiến thức về cơ chế hoạt động của Spring MVC và vai trò của View Resolver. Mặc dù không phải là lựa chọn duy nhất hay hiện đại nhất, JSP vẫn là một phần của hệ sinh thái Spring đã tồn tại và hoạt động hiệu quả trong nhiều năm.

Hy vọng bài viết này hữu ích cho hành trình của bạn trên Lộ trình Java Spring. Trong các bài viết tiếp theo, chúng ta sẽ tiếp tục khám phá các khía cạnh khác của Spring và các công nghệ liên quan!

Hẹn gặp lại các bạn trong những bài viết tiếp theo!

“`

Chỉ mục