Spring with Thymeleaf Pagination for a List – Spring与百里香的列表分页

最后修改: 2018年 6月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview 

1.概述

In this quick tutorial, we’ll build a simple application to display a list of items with pagination using Spring and Thymeleaf.

在这个快速教程中,我们将构建一个简单的应用程序,使用Spring和Thymeleaf显示一个带分页的项目列表。

For an introduction on how to integrate Thymeleaf with Spring, please take a look at our article here.

关于如何将Thymeleaf与Spring集成的介绍,请看我们的文章这里

2. Maven Dependencies

2.Maven的依赖性

Besides the usual Spring dependencies, we’ll add the dependencies for Thymeleaf and Spring Data Commons:

除了常见的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>

We can find the latest thymeleaf-spring5 and spring-data-commons dependencies in the Maven Central repository.

我们可以在Maven Central仓库中找到最新的thymeleaf-spring5spring-data-commons依赖项。

3. Models

3.模型

Our sample application will demonstrate pagination for a list of books.

我们的示例应用程序将展示一个图书列表的分页。

First, let’s define a Book class with two fields and an all-arguments constructor:

首先,让我们定义一个有两个字段和一个全参数构造函数的Book类。

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

    // standard constructor, setters and getters
}

4. Service

4.服务

Then we’ll create a service to generate the paginated book list for the requested page using the Spring Data Commons library:

然后我们将创建一个服务,使用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;
    }
}

In the above service, we created a method to return the selected Page based on requested page, which is represented by the Pageable interface. The PageImpl class helps to filter out the paginated list of books.

在上述服务中,我们创建了一个方法来返回基于请求的页面所选择的Page,它由Pageable接口表示。PageImpl类有助于过滤出分页的书籍列表。

5. Spring Controller

5.Spring控制器

We’ll need a Spring controller to retrieve the book list of a selected page when given the page size and current page number.

我们需要一个Spring控制器来当给定页面大小和当前页码时,检索所选页面的图书列表

To use the default values for selected page and page size, we can simply access the resource at /listBooks, without any parameters.

要使用选定页面和页面大小的默认值,我们可以简单地访问/listBooks的资源,而不需要任何参数。

If any page size or specific page is required, we can add parameters page and size.

如果需要任何页面大小或特定页面,我们可以添加参数pagesize

For example, /listBooks?page=2&size=6 will retrieve page two with six items per page:

例如,/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";
    }
}

To prepare our pagination for the view, we’ve added model attributes in the Spring controller, including the selected Page and a list of page numbers.

为了给视图准备分页,我们在Spring控制器中添加了模型属性,包括选定的Page和一个页码列表。

6. Thymeleaf Template

6.百里香树叶模板

Now it’s time to create a Thymeleaf template “listBooks.html”, which displays the list of books with pagination based on model attributes from our Spring controller.

现在是时候创建一个Thymeleaf模板“listBooks.html”,该模板根据Spring控制器的模型属性分页显示书籍列表

First, we iterate the list of books and display them in a table. Then we show the pagination when the total number of pages is greater than zero.

首先,我们迭代图书列表,并将其显示在一个表中。然后,我们在总页数大于0时显示分页

Every time we click and select a page, the corresponding list of books will be displayed with the current page link highlighted:

每当我们点击并选择一个页面时,相应的书籍列表就会显示出来,并突出显示当前页面的链接。

<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. Conclusion

7.结语

In this article, we demonstrated how we can paginate a list using Thymeleaf with the Spring framework.

在这篇文章中,我们演示了如何使用Thymeleaf和Spring框架对一个列表进行分页。

As usual, all the code samples used in the article are available over on GitHub.

像往常一样,文章中使用的所有代码样本都可以在GitHub上找到