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

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

Trong bài viết này, chúng ta sẽ hướng dẫn chi tiết về cách tạo một ứng dụng Chat đơn giản với Spring Boot và Websocket.

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.

Trong thế giới công nghệ hiện đại, ứng dụng Chat trở thành một phần không thể thiếu trong cuộc sống hàng ngày của chúng ta. Với sự phát triển của Spring Boot và Websocket, việc tạo ra một ứng dụng Chat đơn giản không còn là điều quá khó khăn.

1. Giới thiệu

websocket png

Giới thiệu chung về Spring Boot và Websocket

Bạn có thể tham khảo các khái niện về Spring Boot trong bài viết này nhé!!!

Vậy Websocket là gì?

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

Websocket là một giao thức truyền tải dữ liệu hai chiều giữa máy chủ và trình duyệt web, cho phép thiết lập một kết nối liên tục và định kỳ giữa chúng. Với Websocket, thông tin có thể được truyền tải theo thời gian thực và có thể được truyền tải nhanh chóng và hiệu quả hơn so với các phương thức truyền tải dữ liệu truyền thống khác như HTTP.

Về cơ bản, Websocket là một cách để thiết lập một kết nối liên tục giữa máy chủ và trình duyệt web, cho phép chúng trao đổi dữ liệu với nhau. Khi kết nối được thiết lập, các thông điệp có thể được gửi và nhận theo thời gian thực và không cần phải thiết lập lại kết nối. Điều này giúp giảm thiểu độ trễ và tăng tốc độ truyền tải dữ liệu trong các ứng dụng đòi hỏi tính năng thời gian thực như Chat, Game, và Video conference.

Mục đích và phạm vi của bài viết

Mục đích của bài viết này là hướng dẫn người đọc cách tạo một ứng dụng Chat đơn giản sử dụng Spring Boot và Websocket. Bài viết sẽ cung cấp cho người đọc một hướng dẫn chi tiết về cách triển khai ứng dụng này, từ khởi tạo dự án đến triển khai ứng dụng.

Phạm vi của bài viết sẽ tập trung vào việc triển khai một ứng dụng Chat đơn giản sử dụng Spring Boot và Websocket. Bài viết sẽ giải thích chi tiết các khái niệm và công nghệ được sử dụng trong ứng dụng, cùng với các bước cụ thể để triển khai ứng dụng. Tuy nhiên, bài viết sẽ không đi sâu vào các khái niệm và tính năng phức tạp của Spring Boot và Websocket, và sẽ tập trung vào việc hướng dẫn người đọc triển khai một ứng dụng Chat đơn giản.

2. Các bước để tạo ứng dụng Chat đơn giản với Spring Boot và Websocket

Chuẩn bị môi trường phát triển

Yêu cầu cấu hình và công cụ cần thiết:

Trước khi bắt đầu, chúng ta cần phải chuẩn bị môi trường phát triển để có thể triển khai ứng dụng Chat đơn giản với Spring Boot và Websocket.

Cụ thể, chúng ta cần có:

  • JDK (Java Development Kit) 11 hoặc mới hơn: JDK là một bộ công cụ phát triển Java được sử dụng để biên dịch và thực thi các chương trình Java. Chúng ta có thể tải và cài đặt JDK từ trang web của Oracle hoặc OpenJDK.

  • Maven: Maven là một công cụ quản lý dự án phổ biến được sử dụng để quản lý các thư viện phụ thuộc và xây dựng các ứng dụng Java. Chúng ta có thể tải và cài đặt Maven từ trang web của Apache Maven.

  • Trình biên dịch code Java: Chúng ta có thể sử dụng một trình biên dịch code Java như Eclipse hoặc IntelliJ IDEA để phát triển ứng dụng.

Cài đặt và cấu hình Spring Boot:

Sau khi đã cài đặt môi trường phát triển, chúng ta cần phải cài đặt và cấu hình Spring Boot. Các bước cài đặt và cấu hình Spring Boot như sau:

Bước 1: Tạo project Spring Boot

Để bắt đầu, chúng ta cần tạo một project Spring Boot mới bằng cách sử dụng Spring Initializr. Chúng ta có thể truy cập Spring Initializr từ trang web của Spring Boot hoặc sử dụng các trình quản lý dự án như Eclipse hoặc IntelliJ IDEA để tạo project Spring Boot.

Bước 2: Thêm các thư viện Spring Boot WebSocket

Sau khi đã tạo project Spring Boot, chúng ta cần thêm các thư viện cần thiết để triển khai WebSocket. Chúng ta có thể thêm các thư viện này vào file pom.xml của project:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
</dependencies>

Bước 3: Cấu hình WebSocket trong ứng dụng

Tiếp theo, chúng ta cần cấu hình WebSocket trong ứng dụng. Chúng ta có thể cấu hình WebSocket bằng cách tạo một class WebSocketConfig trong package config của project:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
 
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatWebSocketHandler(), "/chat");
    }
 
    @Bean
    public WebSocketHandler chatWebSocketHandler() {
        return new ChatWebSocketHandler();

Tạo project Spring Boot:

Và sau đây sẽ là các bước tạo một project Spring boot bằng Spring Initializr

Bước 1: Truy cập trang https://start.spring.io/ để mở Spring Initializr.

b1 png

Bước 2: Chọn các thông số cho project của bạn, bao gồm:

  • Group: Group ID của project, ví dụ com.example.
  • Artifact: Tên của project, ví dụ chat-app.
  • Dependencies: Các dependency cần thiết cho project của bạn. Trong trường hợp này, bạn cần chọn Web và WebSocket.

b2 png

Bước 3: Sau khi chọn các thông số cần thiết, nhấn nút Generate để tạo project của bạn.

b3 png

Bước 4: Sau khi tạo xong, tải project về máy tính của bạn dưới dạng file zip.

b4 png

Bước 5: Giải nén file zip và mở project bằng trình biên dịch của bạn, chẳng hạn như IntelliJ IDEA hay Eclipse.

b5 png

Bước 6: Bây giờ bạn đã có một project Spring Boot với WebSocket được tích hợp sẵn. Bạn có thể tiếp tục triển khai mã nguồn để tạo một ứng dụng Chat đơn giản.

Tạo Model cho ứng dụng

Định nghĩa Model:

  • Định nghĩa các lớp User (người dùng) và Message (tin nhắn) với các thuộc tính tương ứng.
  • Các thuộc tính cho lớp User có thể bao gồm id, username, password, avatar, ... Các thuộc tính cho lớp Message có thể bao gồm id, sender (người gửi), content (nội dung tin nhắn), timestamp (thời gian gửi), ...

Tạo các class để đại diện cho người dùng và tin nhắn

Sau đây là đoạn code ví dụ cho các lớp User và Message:

// Class User
public class User {
    private Long id;
    private String username;
    private String password;
    private String avatar;
    
    // constructor, getter và setter
}

// Class Message
public class Message {
    private Long id;
    private User sender;
    private String content;
    private LocalDateTime timestamp;
    
    // constructor, getter và setter
}

Ở đây, lớp User có các thuộc tính id (mã người dùng), username (tên đăng nhập), password (mật khẩu), và avatar (ảnh đại diện). Lớp Message có các thuộc tính id (mã tin nhắn), sender (người gửi tin nhắn), content (nội dung tin nhắn), và timestamp (thời gian gửi tin nhắn).

Xây dựng Repository

Để sử dụng các lớp này trong ứng dụng, cần tạo các repository để lưu trữ và truy vấn dữ liệu.

Ví dụ, ta có thể sử dụng JPA và Hibernate để lưu trữ dữ liệu trong cơ sở dữ liệu:

// Repository User
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

// Repository Message
@Repository
public interface MessageRepository extends JpaRepository<Message, Long> {
    List<Message> findByOrderByTimestampAsc();
}

Ở đây, UserRepository có phương thức findByUsername() để tìm kiếm người dùng theo tên đăng nhập, còn MessageRepository có phương thức findByOrderByTimestampAsc() để lấy danh sách tin nhắn đã được sắp xếp theo thời gian gửi tăng dần.

Xây dựng giao diện người dùng

Tạo trang đăng nhập

Tạo trang đăng nhập (login page) với form nhập thông tin tài khoản người dùng (username và password).

Ví dụ về template HTML cho trang đăng nhập:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chat App - Login</title>
    <link rel="stylesheet" href="/css/login.css">
</head>
<body>
    <div class="login-container">
        <div class="login-box">
            <h1>Chat App</h1>
            <form id="login-form">
                <div class="form-group">
                    <label for="username">Username:</label>
                    <input type="text" id="username" name="username" placeholder="Enter your username">
                </div>
                <div class="form-group">
                    <label for="password">Password:</label>
                    <input type="password" id="password" name="password" placeholder="Enter your password">
                </div>
                <button type="submit">Login</button>
            </form>
        </div>
    </div>
    <script src="/js/jquery.min.js"></script>
    <script src="/js/login.js"></script>
</body>
</html>

Tạo trang chat

Tạo trang chat (chat page) để hiển thị danh sách tin nhắn và cho phép người dùng gửi tin nhắn mới. Giao diện có thể sử dụng HTML, CSS và JavaScript để tạo ra các thành phần UI cần thiết.

Ví dụ về template HTML cho trang chat:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chat Application</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-4">
                <h3>Welcome, <span id="username"></span>!</h3>
                <div class="online-users">
                    <h4>Online Users:</h4>
                    <ul id="online-users-list"></ul>
                </div>
            </div>
            <div class="col-md-8">
                <div class="chat-box">
                    <ul id ="chat-box-list"></ul>
<form id="chat-form">
<input type="text" id="message-input" placeholder="Type your message...">
<button type="submit">Send</button>
</form>
</div>
</div>
</div>
</div>
<script src="/js/jquery.min.js"></script>
<script src="/js/stomp.min.js"></script>
<script src="/js/chat.js"></script>
</body>
</html>

Và đoạn code JavaScript để kết nối với servergửi nhận tin nhắn:

$(document).ready(function() {
    var stompClient = null;
    var username = null;

    function connect() {
        var socket = new SockJS('/websocket');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            console.log('Connected: ' + frame);
            stompClient.subscribe('/topic/public', function(chatMessage) {
                var message = JSON.parse(chatMessage.body);
                displayMessage(message);
            });
            stompClient.subscribe('/topic/userlist', function(onlineUsers) {
                var users = JSON.parse(onlineUsers.body);
                displayOnlineUsers(users);
            });
            sendUserJoinMessage();
        });
    }

    function sendUserJoinMessage() {
        var chatMessage = {
            senderId: $('#sender-id').val(),
            senderName: $('#sender-name').val(),
            content: '',
            type: 'JOIN'
        };
        stompClient.send('/app/chat.addUser', {}, JSON.stringify(chatMessage));
        username = $('#sender-name').val();
        $('#username').text(username);
    }

    function displayMessage(message) {
        var chatBoxList = $('#chat-box-list');
        var messageClass = 'chat-box-list-item';
        if (message.senderName === username) {
            messageClass += ' chat-box-list-item-mine';
        }
        var messageHtml = '<li class="' + messageClass + '">';
        messageHtml += '<div class="chat-box-list-item-sender">' + message.senderName + '</div>';
        messageHtml += '<div class="chat-box-list-item-content">' + message.content + '</div>';
        messageHtml += '</li>';
        chatBoxList.append(messageHtml);
        chatBoxList.scrollTop(chatBoxList.prop('scrollHeight'));
    }

    function displayOnlineUsers(users) {
        var onlineUsersList = $('#online-users-list');
        onlineUsersList.empty();
        users.forEach(function(user) {
            var userHtml = '<li>' + user.name + '</li>';
            onlineUsersList.append(userHtml);
        });
    }

    $('#chat-form').on('submit', function(e) {
        e.preventDefault();
        var messageInput = $('#message-input');
        var chatMessage = {
            senderId: $('#sender-id').val(),
            senderName: $('#sender-name').val(),
            content: messageInput.val(),
            type: 'CHAT'
        };
        stompClient.send('/app/chat.sendMessage', {}, JSON.stringify(chatMessage));
        messageInput.val('');
    });

    connect();
});

Tạo các controller

Tạo controller cho trang đăng nhập

Tạo một UserController để xử lý các yêu cầu liên quan đến đăng nhập, đăng ký và đăng xuất của người dùng. Điều này có thể được thực hiện bằng cách sử dụng các phương thức POST và GET để lấy thông tin người dùng và thực hiện các hoạt động liên quan đến đăng nhập.

Sau khi đã định nghĩa các lớp và repository, ta có thể xây dựng các controller để xử lý các yêu cầu từ người dùng.

Ví dụ, ta có thể tạo UserController để xử lý yêu cầu đăng nhập và đăng ký:

// UserController
@Controller
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @PostMapping("/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        HttpSession session) {
        User user = userRepository.findByUsername(username);
        if (user != null && user.getPassword().equals(password)) {
            session.setAttribute("user", user);
            return "redirect:/chat";
        } else {
            return "redirect:/login";
        }
    }

    @PostMapping("/register")
    public String register(@ModelAttribute("user") User user) {
        userRepository.save(user);
        return "redirect:/login";
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:/login";
    }
}

Ở đây, phương thức login() sẽ kiểm tra xem người dùng có tồn tại trong cơ sở dữ liệu và có nhập đúng mật khẩu không, nếu đúng thì lưu thông tin người dùng vào session và chuyển hướng sang trang chat, còn nếu sai thì chuyển hướng lại trang đăng nhập. Phương thức register() sẽ lưu thông tin người dùng mới vào cơ sở dữ liệu, còn phương thức logout() sẽ xóa thông tin người dùng khỏi session và chuyển hướng lại trang đăng nhập.

Tạo controller cho trang chat

Tạo một ChatController để xử lý các yêu cầu liên quan đến trao đổi tin nhắn giữa người dùng. Điều này có thể được thực hiện bằng cách sử dụng Websocket để thiết lập kết nối giữa người dùng và máy chủ, và gửi tin nhắn qua kết nối này.

// ChatController
@Controller
public class ChatController {
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private MessageRepository messageRepository;

    @GetMapping("/chat")
    public String chat(Model model, HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "redirect:/login";
        }
        List<Message> messages = messageRepository.findByOrderByTimestampAsc();
        model.addAttribute("user", user);
        model.addAttribute("messages", messages);
        return "chat";
    }

    @MessageMapping("/chat.sendMessage")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(@Payload ChatMessage chatMessage) {
        User sender = userRepository.getOne(chatMessage.getSenderId());
        Message message = new Message();
        message.setSender(sender);
        message.setContent(chatMessage.getContent());
        message.setTimestamp(LocalDateTime.now());
        messageRepository.save(message);
        return chatMessage;
    }

    @MessageMapping("/chat.addUser")
    @SendTo("/topic/public")
    public ChatMessage addUser(@Payload ChatMessage chatMessage,
                               SimpMessageHeaderAccessor headerAccessor) {
        User user = userRepository.getOne(chatMessage.getSenderId());
        headerAccessor.getSessionAttributes().put("user", user);
        return chatMessage;
    }
}

Ở đây, phương thức chat() sẽ kiểm tra xem người dùng đã đăng nhập chưa và lấy danh sách tin nhắn từ cơ sở dữ liệu để hiển thị lên trang chat. Phương thức sendMessage()addUser() sẽ được gọi khi người dùng gửi tin nhắn hoặc tham gia vào phòng chat, và sẽ lưu tin nhắn mới vào cơ sở dữ liệu và gửi lại tin nhắn đó cho tất cả các người dùng khác trong phòng chat.

Đó là các bước để tạo ứng dụng Chat đơn giản với Spring Boot và Websocket. Bạn có thể tự do tùy chỉnh các class và template để phù hợp với nhu cầu của mình nhé!!

3. Xây dựng Websocket

Để xây dựng Websocket cho ứng dụng chat, bạn có thể làm theo các bước sau:

Định nghĩa Websocket endpoint

Bạn cần tạo một class endpoint để định nghĩa các phương thức để xử lý kết nối Websocket và các tin nhắn.

Ví dụ:

import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Component
@EnableWebSocket
public class ChatWebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new ChatWebSocketHandler(), "/chat").setAllowedOrigins("*");
    }
}

Xây dựng logic xử lý tin nhắn trong Websocket

Bạn cần tạo một class để xử lý tin nhắn và kết nối của các client.

Ví dụ:

import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ChatWebSocketHandler extends AbstractWebSocketHandler {

    private Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.put(session.getId(), session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session.getId());
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        for (WebSocketSession s : sessions.values()) {
            s.sendMessage(message);
        }
    }
}

Trong ví dụ này, chúng ta sử dụng một ConcurrentHashMap để lưu trữ các WebSocketSession của các client kết nối tới. Khi có tin nhắn mới, chúng ta sử dụng vòng lặp để gửi tin nhắn đến tất cả các session của client kết nối tới.

Kết nối Websocket với ứng dụng

Bạn cần bổ sung một số cấu hình cho ứng dụng để kết nối với Websocket.

Ví dụ:

@Configuration
public class ChatAppConfig {

    @Bean
    public WebSocketHandler chatWebSocketHandler() {
        return new ChatWebSocketHandler();
    }

    @Bean
    public HandlerMapping webSocketHandlerMapping() {
        Map<String, WebSocketHandler> map = new HashMap<>();
        map.put("/chat", chatWebSocketHandler());

        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
        mapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
        mapping.setUrlMap(map);

        return mapping;
    }

    @Bean
    public WebSocketHandlerAdapter handlerAdapter() {
        return new WebSocketHandlerAdapter();
    }
}

Trong ví dụ này, chúng ta sử dụng các Bean để đăng ký ChatWebSocketHandler, HandlerMapping và WebSocketHandlerAdapter. HandlerMapping giúp định tuyến WebSocket đến ChatWebSocketHandler, trong khi WebSocketHandlerAdapter giúp kết nối Websocket với ứng dụng.

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

Tại sao nên sử dụng Spring Boot và WebSocket để phát triển ứng dụng Chat?

Sử dụng Spring Boot và WebSocket để phát triển ứng dụng Chat có nhiều lợi ích, bao gồm:

  • Dễ dàng triển khai và sử dụng.
  • Hiệu suất cao, giúp giảm thiểu độ trễ và lưu lượng mạng.
  • Hỗ trợ các tính năng bảo mật như xác thực người dùng và mã hóa dữ liệu.
  • Được cộng đồng lớn hỗ trợ và phát triển.

WebSocket có thể sử dụng được trên các trình duyệt nào?

WebSocket được hỗ trợ trên hầu hết các trình duyệt hiện đại như Chrome, Firefox, Safari và Edge.

Tôi cần phải cài đặt gì để sử dụng WebSocket trên Spring Boot?

Bạn không cần phải cài đặt thêm bất kỳ thư viện nào để sử dụng WebSocket trên Spring Boot, bởi vì nó được tích hợp sẵn trong Spring Framework. Bạn chỉ cần định nghĩa WebSocket endpoint và xây dựng các phương thức xử lý tin nhắn cho nó.

5. Kết bài viết

Cảm ơn bạn đã theo dõi và đọc hết nội dung này. Hy vọng bài viết đã giúp bạn hiểu rõ hơn về cách phát triển ứng dụng Chat đơn giản với Spring Boot và WebSocket. Nếu bạn có bất kỳ câu hỏi hoặc ý kiến đóng góp nào, xin hãy để lại trong phần bình luận bên dưới. Cảm ơn bạn rất nhiều và chúc bạn thành công trong việc phát triển ứng dụng 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

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

Xác định đường biên(boundary traversal) của cây nhị phân trong Java

Xác định đường biên(boundary traversal) của cây nhị phân trong Java

Top