You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Thymeleaf实现全站URL显示Gallery动态子菜单

Hey there! Let's break down how to implement this global gallery submenu that shows up on every page, pulling data straight from MySQL. Since you already have your page fragments split (header, footer), we'll focus on integrating the dynamic data seamlessly across all your pages.

First, map your MySQL gallery table to a Java entity. Make sure the fields match your actual table structure:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Gallery {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name; // Stores "Gallery1", "Gallery2", "Gallery3" etc.
    private String url; // Optional: links each submenu to a specific page

    // Getters & Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getUrl() { return url; }
    public void setUrl(String url) { this.url = url; }
}

2. Build a Repository Interface

Use Spring Data JPA to handle database interactions with minimal code:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface GalleryRepository extends JpaRepository<Gallery, Long> {
    // We'll use the default findAll() method to fetch all gallery entries
}

Separate business logic from controllers with a service class:

import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class GalleryService {
    private final GalleryRepository galleryRepository;

    // Constructor injection (preferred over @Autowired)
    public GalleryService(GalleryRepository galleryRepository) {
        this.galleryRepository = galleryRepository;
    }

    public List<Gallery> getAllGalleries() {
        return galleryRepository.findAll();
    }
}

This is the critical step! To ensure every page can access the gallery submenu data, use @ControllerAdvice with @ModelAttribute. This adds the gallery list to the model for every incoming request:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import java.util.List;

@ControllerAdvice
public class GlobalControllerAdvice {
    private final GalleryService galleryService;

    public GlobalControllerAdvice(GalleryService galleryService) {
        this.galleryService = galleryService;
    }

    @ModelAttribute("galleries")
    public List<Gallery> getGalleries() {
        return galleryService.getAllGalleries();
    }
}

5. Update Your Header Fragment

Modify your Thymeleaf header fragment to render the dynamic submenus. Here's a sample implementation:

Example Header Fragment with Dynamic Gallery Submenu:

<header>
    <nav>
        <ul class="main-menu">
            <li><a th:href="@{/home}">Home</a></li>
            <li class="dropdown">
                <a href="#">Gallery</a>
                <ul class="submenu">
                    <!-- Iterate over the global galleries model attribute -->
                    <th:block th:each="gallery : ${galleries}">
                        <li><a th:href="@{${gallery.url}}" th:text="${gallery.name}"></a></li>
                    </th:block>
                </ul>
            </li>
            <li><a th:href="@{/about}">About</a></li>
            <!-- Other menu items -->
        </ul>
    </nav>
</header>

Here's how your header appears with the populated submenus:
Header with Gallery Submenus

6. Verify Across All Pages

Thanks to @ControllerAdvice, you don't need to manually add gallery data to any controller's model. For example, a simple Home controller works perfectly without extra code:

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

@Controller
public class HomeController {
    @GetMapping("/home")
    public String home() {
        // Galleries are already added to the model globally!
        return "home";
    }
}

Just include your header fragment in any template (like home.html) as you normally would:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home Page</title>
</head>
<body>
    <div th:replace="fragments/header :: header"></div>
    <!-- Rest of your home page content -->
</body>
</html>

Quick Pro Tips

  • To sort gallery entries alphabetically, update the service method: return galleryRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
  • Add caching to reduce database hits: Annotate getAllGalleries() with @Cacheable("galleries") and enable caching with @EnableCaching in your main Spring Boot application class.

内容的提问来源于stack exchange,提问作者Nobita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:01:04