By kswaughs | Friday, April 29, 2016

Spring Pagination Example

Spring MVC Framework provides pagination capabilities for web pages with PagedListHolder class. In this example, we will see how to develop an online phone store application that displays list of the phones available with a specified number of phones and allows user to choose the next or previous list including required page index. Follow the below steps in developing this application.

1. Maven Dependencies

2. Define Service & model classes

3. Define pagination logic in Controller

4. Define Spring MVC Configuration

5. Servlet Configuration

6. JSPs implementation

1. Maven Dependencies

pom.xml
<dependencies>
   <!--Spring framework related jars-->
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.2.10.RELEASE</version>
   </dependency>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
   </dependency>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
   </dependency>
</dependencies>

2. Define Service & model classes

Create a Service class that returns the list of phone objects.

PhoneService
package com.kswaughs.web.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.kswaughs.web.beans.Phone;

@Service
public class PhoneService {
    
    public List<Phone> getPhoneslist() {
        
        List<Phone> phonesList = new ArrayList<Phone>();
        
        phonesList.add(buildPhone("1", "Samsung Galaxy Y"));
        phonesList.add(buildPhone("2", "Nokia Lumia"));
        phonesList.add(buildPhone("3", "Moto G"));
        phonesList.add(buildPhone("4", "Lenovo A 7000 white"));
        phonesList.add(buildPhone("5", "Sony XPeria"));
        
        return phonesList;
    }
    
    private Phone buildPhone(String id, String name) {
        
        Phone phone = new Phone(id, name);
        return phone;
    }
    
}

Below is the Data Model class to hold phone details.

Phone
package com.kswaughs.web.beans;

public class Phone {
    
    private String id;
    
    private String name;
    
    public Phone() {
        
    }
    
    public Phone(String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}

3. Define pagination logic in Controller

Create a Controller class to handle the requests and define the pagination logic.

PhoneController
package com.kswaughs.web.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.support.PagedListHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.kswaughs.web.beans.Phone;
import com.kswaughs.web.service.PhoneService;

@Controller
@RequestMapping(value = "/phones")
public class PhoneController {
    
    @Autowired
    PhoneService phoneSvc;
    
    @RequestMapping(value = {"/all/{type}","/all"}, method = RequestMethod.GET)
    public ModelAndView all(
            @PathVariable Map<String, String> pathVariablesMap, 
            HttpServletRequest req) {
        
        PagedListHolder<Phone> productList = null;
        
        String type = pathVariablesMap.get("type");
        
        if(null == type) {
            // First Request, Return first set of list
            List<Phone> phonesList = phoneSvc.getPhoneslist();
            
            productList = new PagedListHolder<Phone>();
            productList.setSource(phonesList);
            productList.setPageSize(2);
            
            req.getSession().setAttribute("phonesList",  productList);
        
            printPageDetails(productList);
            
        } else if("next".equals(type)) {
            // Return next set of list
            productList = (PagedListHolder<Phone>) req.getSession()
                                .getAttribute("phonesList");
            
            productList.nextPage();
            
            printPageDetails(productList);
            
        } else if("prev".equals(type)) {
            // Return previous set of list
            productList = (PagedListHolder<Phone>) req.getSession()
                                .getAttribute("phonesList");
            
            productList.previousPage();
            
            printPageDetails(productList);
            
        } else {
            // Return specific index set of list
            System.out.println("type:" + type);
            
            productList = (PagedListHolder<Phone>) req.getSession()
                                .getAttribute("phonesList");
            
            int pageNum = Integer.parseInt(type);
            
            productList.setPage(pageNum);
            
            printPageDetails(productList);
        }
                    
        ModelAndView mv = new ModelAndView("index");
        
        return  mv;
    }

    private void printPageDetails(PagedListHolder productList) {
        
        System.out.println("curent page - productList.getPage() :"
                + productList.getPage());
        
        System.out.println("Total Num of pages - productList.getPageCount :"
                + productList.getPageCount());
        
        System.out.println("is First page - productList.isFirstPage :"
                + productList.isFirstPage());
        
        System.out.println("is Last page - productList.isLastPage :"
                + productList.isLastPage());
    }
}

4. Define Spring MVC Configuration

Spring Configuration defined with annotations.

SpringWebConfig
package com.kswaughs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc 
@Configuration
@ComponentScan({ "com.kswaughs.web" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
    
    @Bean
    public ViewResolver jspViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/jsps/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }        
}

5. Servlet Configuration

Create below servlet initialization class.

SpringWebInitializer
package com.kswaughs.servlet;

import org.springframework.web.servlet.support.
    AbstractAnnotationConfigDispatcherServletInitializer;

import com.kswaughs.config.SpringWebConfig;

public class SpringWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[] { SpringWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[] {};
    }
    
}

6. JSPs implementation

JSP page that displays the list of phones available.

index.jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
    <spring:url value="/resources/css/style.css" var="style" />
    <spring:url value="/phones/all" var="pageurl" />
    <link href="${style}" rel="stylesheet" />
    </head>
    <body>
    <div>
        <p>Welcome to Phones Store</p>
        <p>List of the Phones in our store.</p>
    </div>
    <div>
        <c:set var="pageListHolder" value="${phonesList}" scope="session" />
        <table cellspacing="0">
            <thead><tr><th>ID</th><th>Name</th></tr></thead>
            <tbody>
            <c:forEach var="ph" items="${pageListHolder.pageList}">
                <tr><td>${ph.id}</td><td>${ph.name}</td></tr>
            </c:forEach>
            </tbody>
        </table>
    </div>
    <div>
    <span style="float:left;">
    <c:choose>
        <c:when test="${pageListHolder.firstPage}">Prev</c:when>
        <c:otherwise><a href="${pageurl}/prev">Prev</a></c:otherwise>
    </c:choose>
    </span>
    <span>
    <c:forEach begin="0" end="${pageListHolder.pageCount-1}" varStatus="loop">
    &nbsp;&nbsp;
    <c:choose>
        <c:when test="${loop.index == pageListHolder.page}">${loop.index+1}</c:when>
        <c:otherwise><a href="${pageurl}/${loop.index}">${loop.index+1}</a></c:otherwise>
    </c:choose>
    &nbsp;&nbsp;
    </c:forEach>
    </span>
    <span>
    <c:choose>
        <c:when test="${pageListHolder.lastPage}">Next</c:when>
        <c:otherwise><a href="${pageurl}/next">Next</a></c:otherwise>
    </c:choose>
    </span>
    </div>
    </body>
</html>

css file to display the table with border

styles.css
html, body {
    height: 100%;
}
html {
    display: table;
    margin: auto;
 position: relative;
    min-width: 500px;
    min-height: 768px;
    height: 100%;
}
body {
  display: table-cell;
  font: 13px/20px 'Lucida Grande', Tahoma, Verdana, sans-serif;
  color: #404040;
  background: #ffffff;
  text-align: center;
}
div {
 margin-left: 10 px;
 text-align: left;
}
table {
text-align:center;
font-family:Arial, Helvetica, sans-serif;
color:#000;
font-size:14px;
text-shadow: 1px 1px 0px #fff;
background:#ededed;
margin:20px;
border:#ccc 1px solid;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
-moz-box-shadow: 0 1px 2px #d1d1d1;
-webkit-box-shadow: 0 1px 2px #d1d1d1;
box-shadow: 0 1px 2px #d1d1d1;

}
table th {
padding:21px 25px 22px 25px;
border-top:1px solid #fafafa;
border-bottom:1px solid #e0e0e0;
background: #ededed;
background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb));
background: -moz-linear-gradient(top,  #ededed,  #ebebeb);
}
table a:link {
color: #666;
font-weight: bold;
text-decoration:none;
}
table a:visited {
color: #999999;
font-weight:bold;
text-decoration:none;
}
table a:active,
table a:hover {
color: #bd5a35;
text-decoration:underline;
}
table tr:first-child th:first-child {
-moz-border-radius-topleft:3px;
-webkit-border-top-left-radius:3px;
border-top-left-radius:3px;
}
table tr:first-child th:last-child {
-moz-border-radius-topright:3px;
-webkit-border-top-right-radius:3px;
border-top-right-radius:3px;
}
table tr {
text-align: left;
padding-left:20px;
}
table td:first-child {
text-align: left;
padding-left:20px;
border-left: 0;
}
table td {
padding:18px;
border-top: 1px solid #ffffff;
border-bottom:1px solid #e0e0e0;
border-left: 1px solid #e0e0e0;
background: #ffffff;
background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa));
background: -moz-linear-gradient(top,  #fbfbfb,  #fafafa);
}
table tr.even td {
background: #ffffff;
background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6));
background: -moz-linear-gradient(top,  #f8f8f8,  #f6f6f6);
}
table tr:last-child td {
border-bottom:0;
}
table tr:last-child td:first-child {
-moz-border-radius-bottomleft:3px;
-webkit-border-bottom-left-radius:3px;
border-bottom-left-radius:3px;
}
table tr:last-child td:last-child {
-moz-border-radius-bottomright:3px;
-webkit-border-bottom-right-radius:3px;
border-bottom-right-radius:3px;
}
table tr:hover td {
background: #f2f2f2;
background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0));
background: -moz-linear-gradient(top,  #f2f2f2,  #f0f0f0);
}

Testing the application

First page

http://localhost:8080/spring_app/phones/all

Recommend this on


7 comments:

  1. I need source code can u plz give me ???

    ReplyDelete
    Replies
    1. already there. why so lazy?

      Delete
    2. i want source code because i didnt get our error plz send on my mail chaman1989srivastav@gmail.com

      Delete
  2. Hi Can you please share the eclipse source code. I am new to spring framework, not sure how to place the configutation classes. my email id attituethebest@GMAIL.COM

    ReplyDelete
  3. Thankyou, used your code(service and jsp example) on my project and work nicely!

    ReplyDelete
  4. Follow this post http://www.solutionfactory.in/posts/Create-Dynamic-Pagination-using-Java-Spring-Boot-Hibernate-and-MySQL , it has very easy spring pagination tutorial.

    ReplyDelete