SPRING BOOT
Cách sử dụng Spring Scheduled trong Spring Boot Hướng dẫn CRUD với Spring Boot, REST và AngularJS trong Java Hướng dẫn Upload file với Spring Boot trong Java Hướng dẫn download file với Spring Boot trong Java Hướng dẫn Upload file với Spring Boot và jQuery Ajax trong Java Spring Boot là gì? Tại sao sử dụng Spring Boot trong Java Cài đặt Spring Boot trong Java, code một project Spring Boot cơ bản RESTful API là gì? Cách hoạt động của RESTful API trong Spring Boot RESTful API hoạt động qua giao thức HTTP như thế nào? CRUD đơn giản với RESTful API trong Spring Boot Java Các thuộc tính của Spring Boot trong Java Hướng dẫn sử dụng Thymeleaf và Spring Boot trong Java Hướng dẫn sử dụng FreeMarker với Spring Boot trong Java Hướng dẫn sử dụng JSP và Spring Boot trong Java Cách dùng Logging trong Spring Boot Kiến trúc 3layer trong Spring Boot là gì? Cách hoạt động thế nào? Hướng dẫn sử dụng Apache Tiles với Spring Boot trong Java Sử dụng nhiều ViewResolver trong Spring Boot Java Giới thiệu về Spring Boot Actuator trong ứng dụng Spring Boot Cách dùng Spring JDBC trong ứng dụng Spring Boot Java Spring Data JPA trong Spring Boot là gì? Spring Data JPA có gì hay? Tương tác giữa Spring Boot, JPA và cơ sở dữ liệu H2 Cách dùng Spring Email trong Spring Boot Sử dụng @bean trong ứng dụng Spring Boot Cách chuyển HTTP sang HTTPS trong Spring Boot Bảo mật Spring Boot RESTful Service sử dụng Basic Authentication trong Java Cách dùng Spring Security trong Spring Boot để xác thực và phân quyền Cách triển khai Spring Boot trên Tomcat Server Sử dụng JUnit để tạo unit test trong Spring Boot Cách test RESTful API trong Spring Boot Tạo ứng dụng Chat với Spring Boot và Websocket Tạo trang web đa ngôn ngữ với Spring Boot trong Java Sử dụng Twitter Bootstrap trong Spring Boot Hướng dẫn sử dụng Interceptor trong Spring Boot Cách tạo Restful Client bằng RestTemplate trong Spring Boot Cách dùng Spring Boot và MongoDB trong Java Cách dùng Spring Boot và Mustache trong Java Cách dùng Groovy trong Spring Boot Java
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Sử dụng nhiều ViewResolver trong Spring Boot Java

Trong bài viết này sẽ giúp các bạn hiểu rõ hơn về cách sử dụng nhiều ViewResolver trong Spring Boot và cách chúng hoạt động với nhau như thế nào.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

ViewResolver là một thành phần quan trọng trong Spring Boot, được sử dụng để xác định cách thức hiển thị các view cho người dùng. Trong khi đó, Spring Boot cung cấp khá nhiều loại ViewResolver khác nhau phù hợp với từng nhu cầu khác nhau. Tuy nhiên, trong một số trường hợp, chúng ta có thể cần sử dụng nhiều ViewResolver để xử lý các yêu cầu khác nhau.

1. ViewResolver là gì?

ViewResolver là một thành phần quan trọng trong framework Spring Boot, nó được sử dụng để xác định cách thức hiển thị các view (giao diện người dùng) cho người dùng. Trong Spring Boot, khi một yêu cầu được gửi đến một controller, controller sẽ trả về một đối tượng view (thường là một trang web HTML) để hiển thị cho người dùng. Tuy nhiên, để xác định được view nào cần được hiển thị, Spring Boot sử dụng ViewResolver.

ViewResolver sẽ tìm kiếm và xác định view cụ thể mà controller trả về dựa trên các quy tắc được cấu hình trước đó trong ứng dụng.

Bài viết này được đăng tại [free tuts .net]

Ví dụ, trong trường hợp sử dụng Spring Boot với thư viện tích hợp sẵn Thymeleaf, có thể sử dụng ThymeleafViewResolver để xác định view mà controller trả về là một trang web được tạo ra bằng Thymeleaf.

Một số loại ViewResolver cơ bản trong Spring Boot

Có nhiều loại ViewResolver khác nhau trong Spring Boot, chúng cung cấp các cách thức khác nhau để tìm kiếm và xác định view. Việc chọn ViewResolver phù hợp sẽ phụ thuộc vào loại view mà ứng dụng của bạn sử dụng và yêu cầu cụ thể của dự án. Dưới đây là một số loại ViewResolver cơ bản trong Spring Boot:

  • InternalResourceViewResolver: sử dụng để xác định các file JSP để hiển thị cho người dùng. Nó tìm kiếm các file JSP trong thư mục "WEB-INF/views" và có thể được cấu hình để thêm tiền tố hoặc hậu tố cho tên file JSP.

  • ThymeleafViewResolver: sử dụng để xác định các file HTML được tạo ra bằng Thymeleaf. Nó có thể được cấu hình để tìm kiếm các file HTML trong các thư mục khác nhau và hỗ trợ nhiều tính năng mạnh mẽ của Thymeleaf, bao gồm cả các biểu thức thymeleaf và các thẻ thymeleaf.

  • ResourceBundleViewResolver: sử dụng để xác định các file view trong các file properties của ứng dụng. Nó cho phép tách rời mã ứng dụng và các file view, giúp dễ dàng cập nhật và bảo trì các file view.

  • JsonViewResolver: sử dụng để xác định view là một đối tượng JSON được trả về cho người dùng. Nó cho phép tạo ra các API RESTful dễ dàng và trả về đối tượng JSON đơn giản và dễ đọc cho người dùng.

  • XlsxViewResolver: sử dụng để xác định view là một tệp Excel (xlsx) được tạo ra bằng Apache POI. Nó cho phép tạo ra các báo cáo dạng bảng tính và xuất chúng thành tệp Excel để người dùng có thể tải xuống và sử dụng.

Tùy thuộc vào yêu cầu và loại view của ứng dụng, các loại ViewResolver khác nhau trong Spring Boot có thể được sử dụng để xác định cách thức hiển thị các view cho người dùng.

2. Các bước tạo dự án sử dụng nhiều ViewResolver trong Spring Boot

Hôm nay mình sẽ hướng dẫn các bạn tạo dự án áp dụng nhiều ViewResolver trong Spring Boot, cụ thể ba loại ViewResolver mình sẽ kết hợp trong dự án là: InternalResourceViewResolver, ThymeleafViewResolver FreeMarker cho tầng view

Bước 1: Tạo mới một project với Maven Project.

Bạn hãy mở Eclipse và chọn File > New > Maven Project.

B1 png

Bước 2: Chọn cấu hình cho project.

Chọn Create a simple project (skip archetype selection) và nhấn Next.

simpleProject png

Bước 3: Đặt tên cho project và chọn đường dẫn để lưu trữ project.

Nhập thông tin về Group ID, Artifact ID, và Version. Group ID là tên của nhóm hoặc công ty của bạn, Artifact ID là tên của project và Version là phiên bản của project. Nhấn Next để tiếp tục.

b4 png

Bước 4: Lựa chọn cấu hình phù hợp cho dự án.

Vì chúng ta sẽ sử dụng 3 loại ViewResolver của 3 công nghệ JSP, Thymeleaf và FreeMarker nên chúng ta sẽ phải add cấu hình của 3 loại vào.

Lựa chọn Thymeleaf, FreeMarker và Web sau đó ấn Finish

chonCauHinh png

Sau khi thực hiện đầy đủ các bước trên thì project sẽ được tạo thành công.

3. Cấu hình file pom.xml

Tiếp theo đây mình sẽ hướng dẫn các bạn thêm thư viện vào file pom.xml, bạn có thể tham khảo code một file pom.xml đầy đủ ở bài viết này, sau khi có file pom.xml thì bạn hãy tiến hành add thư viện của các ViewResolver phù hợp vào.

Vì ở đây là ví dụ của mình phải add 3 thư viện JSP, Thymeleaf, FreeMarker vào project nên bên trong file pom.xml phải có 3 dependency của 3 thư viện thì chương trình mới thực thi chạy dự án được.

Đầu tiên là thư viện của Thymeleaf, tiếp đến là thư viện của Web và sau cùng là thư viêjn của FreeMarker, các bạn có thể tham khảo trong đoạn code sau:

<!-- Thymeleaf -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- FreeMarker -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- Web -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JSP -->
<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
   <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- JSTL -->
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
</dependency>

4. Cấu hình các ViewResolver

Tại sao phải cấu hình lại ViewResolver?

Khi phát triển một dự án Spring Boot, bạn thường chỉ sử dụng một công nghệ cho tầng View, và Spring Boot sẽ tự động cấu hình cho bạn một ViewResolver phù hợp với công nghệ đó. Tuy nhiên, nếu bạn muốn sử dụng nhiều công nghệ khác nhau cho tầng View trong cùng một dự án, bạn sẽ cần phải tự cấu hình các ViewResolver tương ứng để Spring Boot có thể hiểu và xử lý đúng cách.

Ví dụ, nếu bạn muốn sử dụng cả JSP và Thymeleaf trong dự án của mình, bạn sẽ cần cấu hình hai ViewResolver khác nhau: một cho JSP và một cho Thymeleaf. Bạn có thể cấu hình các ViewResolver này trong tệp cấu hình của Spring Boot bằng cách sử dụng các lớp như InternalResourceViewResolver cho JSP và ThymeleafViewResolver cho Thymeleaf.

Để nói một cách ngắn gọn hơn thì đối với Spring Boot nếu bạn sử dụng nhiều công nghệ cho tầng View trong dự án Spring Boot của mình, bạn cần tự cấu hình các ViewResolver tương ứng để Spring Boot có thể hiểu và xử lý đúng cách.

Sau đây là sơ đồ luồng đi (flow) của một ứng dụng khi sử dụng một ViewResolver:

luong1 png

Đối với sơ đồ luồng đi của một ứng dụng Spring khi sử dụng nhiều ViewResolver thì sẽ có chút thay đổi, sẽ có nhiều ViewResolver tham gia vào luồng đi (flow) của ứng dụng. Các ViewResolver được sắp xếp theo thứ tự ưu tiên (0, 1, 2, ..). Nếu ViewResolver (0) không tìm thấy "View Name" cần thiết, ViewResolver (1) sẽ được sử dụng, ...

luongnhieu png

Giải pháp:

Để cấu hình ba công nghệ JSP, Thymeleaf và FreeMarker trong cùng một ViewResolver trong Spring Boot, bạn có thể sử dụng đối tượng MultiViewResolver của Spring. MultiViewResolver sẽ cho phép bạn định nghĩa một danh sách các ViewResolver và Spring sẽ lần lượt xử lý các ViewResolver này để tìm kiếm View tương ứng.

Đối với JSP, chúng ta sử dụng đối tượng InternalResourceViewResolver, đối với Thymeleaf, chúng ta sử dụng đối tượng ThymeleafViewResolver và đối với FreeMarker, chúng ta sử dụng đối tượng FreeMarkerViewResolver. Mỗi ViewResolver được cấu hình để xử lý một loại view cụ thể và chúng ta đã thiết lập các đường dẫn và thuộc tính khác cho từng loại view.

Dưới đây là một ví dụ cụ thể về cách cấu hình MultiViewResolver cho ba công nghệ JSP, Thymeleaf và FreeMarker trong Spring Boot:

@Configuration
public class ViewResolverConfig {
 
    @Autowired
    private ApplicationContext applicationContext;
 
    @Bean
    public ViewResolver multiViewResolver() {
        MultiViewResolver resolver = new MultiViewResolver();
        List<ViewResolver> resolvers = new ArrayList<>();
 
        // JSP view resolver
        InternalResourceViewResolver jspResolver = new InternalResourceViewResolver();
        jspResolver.setPrefix("/WEB-INF/jsp/");
        jspResolver.setSuffix(".jsp");
        jspResolver.setViewClass(JstlView.class);
        resolvers.add(jspResolver);
 
        // Thymeleaf view resolver
        ThymeleafViewResolver thymeleafResolver = new ThymeleafViewResolver();
        thymeleafResolver.setTemplateEngine(thymeleafTemplateEngine());
        resolvers.add(thymeleafResolver);
 
        // FreeMarker view resolver
        FreeMarkerViewResolver freeMarkerResolver = new FreeMarkerViewResolver();
        freeMarkerResolver.setPrefix("");
        freeMarkerResolver.setSuffix(".ftl");
        freeMarkerResolver.setViewClass(FreeMarkerView.class);
        resolvers.add(freeMarkerResolver);
 
        resolver.setViewResolvers(resolvers);
        resolver.setOrder(0);
        return resolver;
    }
 
    @Bean
    public SpringTemplateEngine thymeleafTemplateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(thymeleafTemplateResolver());
        return templateEngine;
    }
 
    @Bean
    public SpringResourceTemplateResolver thymeleafTemplateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/WEB-INF/thymeleaf/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        templateResolver.setCharacterEncoding("UTF-8");
        return templateResolver;
    }
 
    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("/WEB-INF/freemarker/");
        return configurer;
    }
}

Sau đây mình sẽ giải thích cụ thể về ví dụ trên.

Trong ví dụ này, chúng ta đã định nghĩa một ViewResolver có tên là multiViewResolver bằng cách sử dụng đối tượng MultiViewResolver. Chúng ta đã tạo một danh sách các ViewResolver bao gồm ba ViewResolver khác nhau cho ba công nghệ khác nhau: JSP, Thymeleaf và FreeMarker.

Tiếp theo, chúng ta cũng đã định nghĩa các Bean khác để hỗ trợ việc cấu hình các công nghệ view này. Đối với Thymeleaf, chúng ta đã định nghĩa các Bean SpringTemplateEngine và SpringResourceTemplateResolver. Đối với FreeMarker, chúng ta đã định nghĩa Bean FreeMarkerConfigurer để cấu hình FreeMarker.

Sau đó, chúng ta đã sử dụng phương thức setViewResolvers() để thiết lập danh sách các ViewResolver và đặt độ ưu tiên cho MultiViewResolver.

Với cấu hình này, khi bạn trả về một tên view từ một phương thức điều khiển trong ứng dụng của bạn, Spring Boot sẽ xử lý danh sách các ViewResolver để tìm kiếm view tương ứng với tên view. Nếu không có ViewResolver nào có thể xử lý view, bạn sẽ nhận được một lỗi.

Ví dụ, nếu tên view của bạn là "example", MultiViewResolver sẽ tìm kiếm view tương ứng với tên "example" trên các đường dẫn "/WEB-INF/jsp/example.jsp", "/WEB-INF/thymeleaf/example.html" và "/WEB-INF/freemarker/example.ftl" để trả về view tương ứng.

5. Controller và Views

Tầng Controller trong ứng dụng Spring sử dụng nhiều ViewResolver

Tầng Controller trong ứng dụng Spring không sử dụng nhiều ViewResolver. Tầng Controller được sử dụng để xử lý các yêu cầu của người dùng và trả về các kết quả tương ứng, bao gồm tên của các view cần hiển thị. Việc xử lý các yêu cầu và trả về các kết quả được thực hiện trong tầng Views, thông qua sử dụng các ViewResolver. Các ViewResolver này được sử dụng để xác định cách thức hiển thị các kết quả trả về, bao gồm cách thức xử lý các tệp mẫu và trả về nội dung đã được xử lý đến người dùng.

Do đó, khi sử dụng nhiều ViewResolver, chúng ta cần cấu hình các ViewResolver tương ứng trong tầng Views để xử lý các loại view khác nhau. Sau đó, tầng Controller sẽ trả về tên của các view cần hiển thị, và các ViewResolver sẽ xử lý các view này và trả về nội dung đã được xử lý để hiển thị đến người dùng.

package org.SpringBoot.viewresolvers.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MainController {

    @RequestMapping(value = { "/testJsp" }, method = RequestMethod.GET)
    public String testJspView() {
        return "testJsp";
    }

    @RequestMapping(value = { "/testThymeleaf" }, method = RequestMethod.GET)
    public String testThymeleafView() {
        return "th_page1";
    }
    
    @RequestMapping(value = { "/testFreeMarker" }, method = RequestMethod.GET)
    public String testFreeMarkerView() {
        return "testFreeMarker";
    }
}

Tầng Views trong ứng dụng Spring sử dụng nhiều ViewResolver

Trong ứng dụng Spring, tầng Views có thể sử dụng nhiều ViewResolver để xử lý các loại view khác nhau. Mỗi ViewResolver được cấu hình để xử lý một loại view cụ thể, ví dụ như JSP, Thymeleaf, FreeMarker, và mỗi ViewResolver sẽ được sắp xếp theo thứ tự ưu tiên.

Khi tầng Controller trả về một tên view, Spring sẽ tìm kiếm view tương ứng trong danh sách các ViewResolver theo thứ tự ưu tiên. Nếu một ViewResolver có thể xử lý view, nó sẽ trả về view tương ứng và quá trình tìm kiếm sẽ kết thúc. Nếu không có ViewResolver nào có thể xử lý view, Spring sẽ trả về một lỗi.

Việc sử dụng nhiều ViewResolver có thể hữu ích khi bạn muốn hỗ trợ nhiều loại view trong ứng dụng của mình.

Ví dụ, bạn có thể sử dụng JSP để hiển thị các trang động, Thymeleaf để hiển thị các trang tĩnh và FreeMarker để hiển thị email template. Bằng cách sử dụng nhiều ViewResolver, bạn có thể cấu hình ứng dụng của mình để hỗ trợ các loại view khác nhau một cách dễ dàng.

Để có thể dễ hình dung hơn, bạn có thể tham khảo ví dụ sau:

Đầu tiên mình phải tạo một file html ở trong folder Thymeleaf để tạo view cho Thymeleaf:

view1 png

Tiếp theo mình sẽ code giao diện cho file này:

<!DOCTYPE html>

<html lang="en">
   <head>
       <title>Thymeleaf</title>
   </head>
   <body>
      <h2>Thymeleaf Page</h2>
      <p>templates/th_page1.html</p>
   </body>
</html>

Và đối với JSP và FreeMarker cũng tạo ra các file html tương tự.

Sau đây là đoạn code giao diện của JSP và FreeMarker:

<!DOCTYPE html>

<html lang="en">
   <head>
       <title>FreeMarker</title>
   </head>
   <body>
      <h2>FreeMarker Page</h2>
      <p>templates/freemarker/testFreeMarker.ftl</p>
   </body>
</html>
<!DOCTYPE html>

<html lang="en">
   <head>
       <title>JSP</title>
   </head>
   <body>
      <h2>JSP Page</h2>
      <p>WEB-INF/jsp/testJsp.jsp</p>
   </body>
</html>

6. Các câu hỏi thường gặp

Tại sao lại cần sử dụng nhiều ViewResolver trong Spring Boot?

Có thể có nhiều lý do để sử dụng nhiều ViewResolver trong Spring Boot, nhưng phổ biến nhất là để hỗ trợ nhiều công nghệ khác nhau cho tầng Views. Ví dụ, một ứng dụng có thể sử dụng JSP, Thymeleaf và FreeMarker để hiển thị các trang khác nhau, và sử dụng các ViewResolver tương ứng để xử lý các công nghệ này.

Làm thế nào để cấu hình nhiều ViewResolver trong Spring Boot?

Để cấu hình nhiều ViewResolver trong Spring Boot, chúng ta có thể sử dụng các bean Spring để cấu hình các ViewResolver tương ứng. Ví dụ, chúng ta có thể sử dụng các bean InternalResourceViewResolver, ThymeleafViewResolver và FreeMarkerViewResolver để cấu hình các ViewResolver cho JSP, Thymeleaf và FreeMarker tương ứng.

Làm thế nào để xác định ViewResolver được sử dụng cho một loại view cụ thể?

Để xác định ViewResolver được sử dụng cho một loại view cụ thể, chúng ta có thể sử dụng thuộc tính "order" của các ViewResolver để xác định thứ tự ưu tiên. ViewResolver với order thấp hơn sẽ được sử dụng trước để xử lý view tương ứng.

Có thể sử dụng các ViewResolver từ các thư viện bên thứ ba trong Spring Boot không?

Có, chúng ta có thể sử dụng các ViewResolver từ các thư viện bên thứ ba trong Spring Boot, bằng cách thêm các phụ thuộc tương ứng vào file pom.xml. Tuy nhiên, chúng ta cần đảm bảo rằng các ViewResolver này tương thích với Spring Boot và các phiên bản của Spring Framework được sử dụng trong dự án của chúng ta.

7. Kết bài viết

Trong bài viết này, chúng tôi đã giới thiệu cách sử dụng nhiều ViewResolver trong Spring Boot và cung cấp một ví dụ cụ thể để minh họa. Hy vọng rằng những thông tin này sẽ giúp bạn hiểu rõ hơn về cách sử dụng nhiều ViewResolver trong Spring Boot và áp dụng chúng vào các dự án của mình.

Cùng chuyên mục:

Hướng dẫn Upload file với Spring Boot và jQuery Ajax trong Java

Hướng dẫn Upload file với Spring Boot và jQuery Ajax trong Java

Hướng dẫn download file với Spring Boot trong Java

Hướng dẫn download file với Spring Boot trong Java

Hướng dẫn Upload file với Spring Boot trong Java

Hướng dẫn Upload file với Spring Boot trong Java

Hướng dẫn CRUD với Spring Boot, REST và AngularJS trong Java

Hướng dẫn CRUD với Spring Boot, REST và AngularJS trong Java

Cách sử dụng Spring  Scheduled trong Spring Boot

Cách sử dụng Spring Scheduled trong Spring Boot

Cách dùng Groovy trong Spring Boot Java

Cách dùng Groovy trong Spring Boot Java

Cách dùng Spring Boot và Mustache trong Java

Cách dùng Spring Boot và Mustache trong Java

Cách dùng Spring Boot và MongoDB trong Java

Cách dùng Spring Boot và MongoDB trong Java

Cách tạo Restful Client bằng RestTemplate trong Spring Boot

Cách tạo Restful Client bằng RestTemplate trong Spring Boot

Hướng dẫn sử dụng Interceptor trong Spring Boot

Hướng dẫn sử dụng Interceptor trong Spring Boot

Sử dụng Twitter Bootstrap trong Spring Boot

Sử dụng Twitter Bootstrap trong Spring Boot

Tạo trang web đa ngôn ngữ với Spring Boot trong Java

Tạo trang web đa ngôn ngữ với Spring Boot trong Java

Tạo ứng dụng Chat với Spring Boot và Websocket

Tạo ứng dụng Chat với Spring Boot và Websocket

Sử dụng JUnit để tạo unit test trong Spring Boot

Sử dụng JUnit để tạo unit test trong Spring Boot

Cách triển khai Spring Boot trên Tomcat Server

Cách triển khai Spring Boot trên Tomcat Server

Cách test RESTful API trong Spring Boot

Cách test RESTful API trong Spring Boot

Cách dùng Spring Security trong Spring Boot để xác thực và phân quyền

Cách dùng Spring Security trong Spring Boot để xác thực và phân quyền

Duyệt cây nhị phân bằng phương pháp inOder trong Java

Duyệt cây nhị phân bằng phương pháp inOder trong Java

Xóa node của cây nhị phân tìm kiếm trong Java

Xóa node của cây nhị phân tìm kiếm trong Java

Bảo mật Spring Boot RESTful Service sử dụng Basic Authentication trong Java

Bảo mật Spring Boot RESTful Service sử dụng Basic Authentication trong Java

Top