Перейти к основному содержимому

Как сделать список с пагинацией на Spring и Thymeleaf?

· 3 мин. чтения

1. Обзор

В этом кратком руководстве мы создадим простое приложение для отображения списка элементов с нумерацией страниц с помощью Spring и Thymeleaf .

Для ознакомления с тем, как интегрировать Thymeleaf со Spring, ознакомьтесь с нашей статьей здесь .

2. Зависимости Maven

Помимо обычных зависимостей Spring, мы добавим зависимости для Thymeleaf и Spring Data Commons:

<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>

Мы можем найти последние зависимости thymeleaf-spring5 и spring-data-commons в репозитории Maven Central.

3. Модели

Наш пример приложения продемонстрирует разбивку на страницы для списка книг.

Во-первых, давайте определим класс Book с двумя полями и конструктором со всеми аргументами:

public class Book {
private int id;
private String name;

// standard constructor, setters and getters
}

4. Сервис

Затем мы создадим сервис для создания списка книг с разбивкой на страницы для запрошенной страницы, используя библиотеку Spring Data Commons:

@Service
public class BookService {

final private List<Book> books = BookUtils.buildBooks();

public Page<Book> findPaginated(Pageable pageable) {
int pageSize = pageable.getPageSize();
int currentPage = pageable.getPageNumber();
int startItem = currentPage * pageSize;
List<Book> list;

if (books.size() < startItem) {
list = Collections.emptyList();
} else {
int toIndex = Math.min(startItem + pageSize, books.size());
list = books.subList(startItem, toIndex);
}

Page<Book> bookPage
= new PageImpl<Book>(list, PageRequest.of(currentPage, pageSize), books.size());

return bookPage;
}
}

В приведенном выше сервисе мы создали метод для возврата выбранной страницы на основе запрошенной страницы, которая представлена интерфейсом Pageable . Класс PageImpl помогает отфильтровать разбитый на страницы список книг.

5. Пружинный контроллер

Нам понадобится контроллер Spring для получения списка книг выбранной страницы при заданном размере страницы и текущем номере страницы .

Чтобы использовать значения по умолчанию для выбранной страницы и размера страницы, мы можем просто получить доступ к ресурсу в /listBooks без каких-либо параметров.

Если требуется какой-либо размер страницы или конкретная страница, мы можем добавить параметры page и size .

Например, /listBooks?page=2&size=6 извлечет вторую страницу с шестью элементами на странице:

@Controller
public class BookController {

@Autowired
private BookService bookService;

@RequestMapping(value = "/listBooks", method = RequestMethod.GET)
public String listBooks(
Model model,
@RequestParam("page") Optional<Integer> page,
@RequestParam("size") Optional<Integer> size) {
int currentPage = page.orElse(1);
int pageSize = size.orElse(5);

Page<Book> bookPage = bookService.findPaginated(PageRequest.of(currentPage - 1, pageSize));

model.addAttribute("bookPage", bookPage);

int totalPages = bookPage.getTotalPages();
if (totalPages > 0) {
List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
.boxed()
.collect(Collectors.toList());
model.addAttribute("pageNumbers", pageNumbers);
}

return "listBooks.html";
}
}

Чтобы подготовить нашу разбивку на страницы для представления, мы добавили атрибуты модели в контроллер Spring , включая выбранную страницу и список номеров страниц.

6. Шаблон листа тимьяна

Теперь пришло время создать шаблон Thymeleaf «listBooks.html» , который отображает список книг с нумерацией страниц на основе атрибутов модели из нашего контроллера Spring .

Сначала мы повторяем список книг и отображаем их в таблице. Затем мы показываем разбиение на страницы, когда общее количество страниц больше нуля .

Каждый раз, когда мы нажимаем и выбираем страницу, будет отображаться соответствующий список книг с выделенной ссылкой на текущую страницу:

<table border="1">
<thead>
<tr>
<th th:text="#{msg.id}" />
<th th:text="#{msg.name}" />
</tr>
</thead>
<tbody>
<tr th:each="book, iStat : ${bookPage.content}"
th:style="${iStat.odd}? 'font-weight: bold;'"
th:alt-title="${iStat.even}? 'even' : 'odd'">
<td th:text="${book.id}" />
<td th:text="${book.name}" />
</tr>
</tbody>
</table>
<div th:if="${bookPage.totalPages > 0}" class="pagination"
th:each="pageNumber : ${pageNumbers}">
<a th:href="@{/listBooks(size=${bookPage.size}, page=${pageNumber})}"
th:text=${pageNumber}
th:class="${pageNumber==bookPage.number + 1} ? active"></a>
</div>

7. Заключение

В этой статье мы продемонстрировали, как мы можем разбить список на страницы, используя Thymeleaf с платформой Spring.

Как обычно, все примеры кода, использованные в статье, доступны на GitHub .