Seth Barrett

Daily Blog Post: April 22th, 2023

java

Apr 22th, 2023

Creating Dynamic HTML Templates Using Thymeleaf

In the previous post, we showed you how to use Hibernate to store and retrieve data from a MySQL database. In this post, we'll explore how to use Thymeleaf to create dynamic HTML templates for your Java web application.

Thymeleaf is a popular template engine for Java that allows you to create dynamic HTML pages by combining static HTML with dynamic data. It provides a powerful set of features for templating, including conditional statements, iteration, and variable interpolation.

Step 1: Add Thymeleaf Dependency

To add Thymeleaf to your project, you can add the following dependency to your pom.xml file:

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

Step 2: Create a Thymeleaf Template

To create a Thymeleaf template, you can create a new HTML file in the "src/main/resources/templates" directory and add the following lines:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Note App</title>
</head>
<body>
    <h1>Note App</h1>
    
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Title</th>
                <th>Content</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="note : ${notes}">
                <td th:text="${note.id}"></td>
                <td th:text="${note.title}"></td>
                <td th:text="${note.content}"></td>
            </tr>
        </tbody>
    </table>
    
    <form th:action="@{/notes}" th:object="${note}" method="post">
        <input type="text" th:field="*{title}" placeholder="Title" />
        <input type="text" th:field="*{content}" placeholder="Content" />
        <button type="submit">Save</button>
    </form>
</body>
</html>

This template defines a simple HTML page that displays a table of Note objects and a form for creating new notes. The Thymeleaf expressions are used to iterate over the list of notes and bind the form fields to the Note object.

Step 3: Modify Your Controller

To modify your controller to use the Thymeleaf template, you can modify the NoteController class from the previous post to return the template name and model attributes:

package com.example.notes;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/notes")
public class NoteController {
    
    @Autowired
    private NoteRepository noteRepository;

    @GetMapping("")
    public String getNotes(Model model) {
        model.addAttribute("notes", noteRepository.findAll());
        model.addAttribute("note", new Note());
        return "notes";
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<Note> getNoteById(@PathVariable("id") Long id) {
        Note note = noteRepository.findById(id).orElse(null);
        if (note == null) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(note);
        }
    }
    
    @PostMapping("")
    public ResponseEntity<Note> createNote(@RequestBody Note note) {
    Note savedNote = noteRepository.save(note);
    return ResponseEntity.status(HttpStatus.CREATED).body(savedNote);
    }
    @PutMapping("/{id}")
    public ResponseEntity<Note> updateNote(@PathVariable("id") Long id, @RequestBody Note note) {
        Note existingNote = noteRepository.findById(id).orElse(null);
        if (existingNote == null) {
            return ResponseEntity.notFound().build();
        } else {
            existingNote.setTitle(note.getTitle());
            existingNote.setContent(note.getContent());
            Note updatedNote = noteRepository.save(existingNote);
            return ResponseEntity.ok(updatedNote);
        }
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteNoteById(@PathVariable("id") Long id) {
        noteRepository.deleteById(id);
        return ResponseEntity.noContent().build();
    }
}

Step 4: Test Your Thymeleaf Template

To test your Thymeleaf template, you can modify the NoteController class from the previous post to use the Thymeleaf template:

package com.example.notes;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/notes")
public class NoteController {
    
    @Autowired
    private NoteRepository noteRepository;

    @GetMapping("")
    public String getNotes(Model model) {
        model.addAttribute("notes", noteRepository.findAll());
        model.addAttribute("note", new Note());
        return "notes";
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<Note> getNoteById(@PathVariable("id") Long id) {
        Note note = noteRepository.findById(id).orElse(null);
        if (note == null) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(note);
        }
    }
    
    @PostMapping("")
    public ResponseEntity<Note> createNote(@ModelAttribute Note note) {
        Note savedNote = noteRepository.save(note);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedNote);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<Note> updateNote(@PathVariable("id") Long id, @ModelAttribute Note note) {
        Note existingNote = noteRepository.findById(id).orElse(null);
        if (existingNote == null) {
            return ResponseEntity.notFound().build();
        } else {
            existingNote.setTitle(note.getTitle());
            existingNote.setContent(note.getContent());
            Note updatedNote = noteRepository.save(existingNote);
            return ResponseEntity.ok(updatedNote);
        }
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteNoteById(@PathVariable("id") Long id) {
        noteRepository.deleteById(id);
        return ResponseEntity.noContent().build();
    }
}

You can then run the application using the "mvn spring-boot:run" command and test the web application by navigating to "http://localhost:8080/notes" in your web browser.

Congratulations! You've successfully used Thymeleaf to create dynamic HTML templates for your Java web application. In the final post of this series, we'll wrap up by summarizing what we've learned and pointing you to additional resources for learning Java and Maven.