මාතෘකාව 7: Frontend මූලිකාංග (වෛකල්පිතයි)

අපි backend සහ frontend අතර පාලමක් ගොඩනගමින්, අපගේ දත්ත Spring Boot සහ Thymeleaf සමඟින් දෘශ්‍යමාන කරමු.

Backend API සහ Server-Side Rendering

මේ දක්වා, අපගේ Spring Boot යෙදුම backend API එකක් ලෙස ක්‍රියා කළ අතර, වෙනත් යෙදුම්වලට භාවිතා කිරීම සඳහා JSON දත්ත ආපසු ලබා දුන්නේය. මෙම වෛකල්පිත මාතෘකාවේදී, අපි server-side rendering ගවේෂණය කරන්නෙමු. මෙහිදී අපගේ Spring යෙදුම විසින්ම සම්පූර්ණ HTML පිටු ජනනය කර පරිශීලකයාගේ බ්‍රව්සරයට සෘජුවම සපයයි.

7.1 Spring Boot සමඟ Thymeleaf භාවිතා කිරීම

Thymeleaf යනු නවීන server-side Java template engine එකකි. එය "HTML වලට වැඩි බලයක් ලබා දීමක්" ලෙස සිතන්න. එය ඔබට ඔබගේ HTML ගොනු තුළට logic සහ placeholders ඇතුළත් කිරීමට ඉඩ සලසයි, ඉන්පසු server එක මගින් ඒවා සැබෑ දත්ත සමඟ ප්‍රතිස්ථාපනය කර අවසන් HTML පිටුව බ්‍රව්සරයට යවයි.

Thymeleaf භාවිතා කරන්නේ ඇයි?

  • Spring සමඟ ඇති පහසු සම්බන්ධතාවය: එය Spring Boot සඳහා නිර්දේශිත template engine එකයි.
  • ස්වාභාවික සැකිලි (Natural Templating): Thymeleaf ගොනුවක් තවමත් වලංගු HTML ගොනුවකි. ඔබට එය බ්‍රව්සරයක විවෘත කළ හැකි අතර එය සාමාන්‍ය වෙබ් පිටුවක් මෙන් පෙනෙනු ඇත.

Setup කිරීම

ආරම්භ කිරීම සඳහා ඔබගේ pom.xml වෙත එක් dependency එකක් එක් කිරීම පමණක් ප්‍රමාණවත් වේ.


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

දැන් Spring Boot විසින් ස්වයංක්‍රීයව ඔබගේ HTML template ගොනු src/main/resources/templates/ directory එක තුළ සොයනු ඇත.

7.2 Login වීම සඳහා සරල HTML පිටුවක් ගොඩනැගීම

අපි browser එකේ default pop-up එක වෙනුවට පරිශීලක-හිතකාමී login පිටුවක් නිර්මාණය කරමු.

පියවර 1: MVC Controller

Login පිටුව සඳහා වන ඉල්ලීම හැසිරවීමට අපට controller එකක් අවශ්‍ය වේ. මෙහිදී අපි @RestController වෙනුවට @Controller භාවිතා කරන බව සලකන්න. @Controller මගින් view නාමයක් (HTML ගොනුවේ නම) ආපසු ලබා දෙන අතර, @RestController මගින් දත්ත (JSON වැනි) ආපසු ලබා දෙයි.


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class AuthController {

    // පරිශීලකයෙකු "/login" වෙත ගිය විට, මෙම method එක ක්‍රියාත්මක වේ.
    @GetMapping("/login")
    public String loginPage() {
        // "login" යන string එක ආපසු ලබා දෙයි. Spring Boot + Thymeleaf විසින්
        // src/main/resources/templates/ තුළ "login.html" නමින් ගොනුවක් සොයනු ඇත.
        return "login";
    }
}

පියවර 2: Thymeleaf Template (`login.html`)

src/main/resources/templates/ තුළ login.html නමින් ගොනුවක් සාදන්න.


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>බැංකු ගිණුමට පිවිසෙන්න</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <h2>ඔබගේ බැංකු ගිණුමට පිවිසෙන්න</h2>
        <!-- Spring Security මෙම form submission එක ස්වයංක්‍රීයව හසුරුවනු ඇත -->
        <form th:action="@{/login}" method="post">
            <div class="mb-3">
                <label for="username" class="form-label">Username</label>
                <input type="text" id="username" name="username" class="form-control" required>
            </div>
            <div class="mb-3">
                <label for="password" class="form-label">Password</label>
                <input type="password" id="password" name="password" class="form-control" required>
            </div>
            <button type="submit" class="btn btn-primary">පිවිසෙන්න</button>
        </form>
    </div>
</body>
</html>

7.3 පාරිභෝගික ශේෂය සහ ගනුදෙනු ඉතිහාසය ප්‍රදර්ශනය කිරීම

පරිශීලකයෙකු login වූ පසු, අපි ඔවුන්ගේ ගිණුම් තොරතුරු dashboard පිටුවක පෙන්වීමට බලාපොරොත්තු වෙමු.

පියවර 1: Dashboard Controller

මෙම controller එක මගින් login වී සිටින පරිශීලකයාගේ දත්ත ලබාගෙන, එය Model object එකක් හරහා Thymeleaf template එකට යවනු ඇත.


@Controller
public class DashboardController {

    @Autowired
    private AccountService accountService;

    @GetMapping("/dashboard")
    public String showDashboard(Model model, Authentication authentication) {
        // 'authentication.getName()' මගින් login වී සිටින පරිශීලකයාගේ username එක ලබා දෙයි
        String username = authentication.getName();
        
        // username එක මගින් ගිණුම් ලබා ගැනීමට service method එකක් අපට තිබිය යුතුය
        List<Account> accounts = accountService.getAccountsByUsername(username);
        
        // දත්ත model එකට එක් කරන්න. Template එකට දැන් "userName" සහ "userAccounts" වෙත පිවිසිය හැක.
        model.addAttribute("userName", username);
        model.addAttribute("userAccounts", accounts);
        
        return "dashboard"; // dashboard.html render කරයි
    }
}

පියවර 2: Dashboard Template (`dashboard.html`)

මෙම template එක දත්ත පෙන්වීමට th:text සහ collections හරහා loop වීමට th:each වැනි Thymeleaf attributes භාවිතා කරයි.


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>ගිණුම් Dashboard</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <!-- Model එකෙන් 'userName' attribute එක පෙන්වීමට th:text භාවිතා කිරීම -->
        <h2 th:text="'ආයුබෝවන්, ' + ${userName} + '!' ">ආයුබෝවන්!</h2>
        
        <h3 class="mt-4">ඔබගේ ගිණුම්</h3>
        
        <!-- ගිණුම් ලැයිස්තුව හිස් දැයි පරීක්ෂා කිරීමට th:if භාවිතා කිරීම -->
        <div th:if="${#lists.isEmpty(userAccounts)}">
            <p>ඔබට තවමත් කිසිදු ගිණුමක් නොමැත.</p>
        </div>
        
        <!-- ලැයිස්තුව හිස් නැතිනම් පමණක් table එක render කිරීමට th:unless භාවිතා කිරීම -->
        <table class="table table-striped" th:unless="${#lists.isEmpty(userAccounts)}">
            <thead>
                <tr><th>ගිණුම් අංකය</th><th>ශේෂය</th></tr>
            </thead>
            <tbody>
                <!-- userAccounts ලැයිස්තුව හරහා loop වීමට th:each භාවිතා කිරීම -->
                <tr th:each="account : ${userAccounts}">
                    <td th:text="${account.id}">12345</td>
                    <td th:text="'රු. ' + ${#numbers.formatDecimal(account.balance, 1, 'COMMA', 2, 'POINT')}">රු. 1,000.00</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>