Detailed explanation of universal paging (front-end)

Table of contents

1. Analysis

1.1. Understand its ideas

1.2. Understand its concept 

 1.3. Understand its benefits

2. Optimize pagebean

 3. Develop custom jsp tags for pagination

3.1 Create PageTag class

3.2 Create configuration file (tld) file

3.3BookList

3.4BookServlet

3.5 filter

 

Finally, the detailed explanation of paging (front-end) ends here. I wish everyone a smooth journey on the way to coding!

Thank you everyone for watching!! ! ! ! !


1. Analysis

1.1. Understand its ideas

In front-end development, paging function is a common requirement. It allows users to browse and navigate large amounts of data through page switching, providing a better user experience. The following is a general pagination detailed front-end idea:

  1. Get data:First, you need to obtain the data that needs to be displayed in pages through the interface or other means. Data can be requested asynchronously using Ajax or other data retrieval methods.

  2. Data processing:After obtaining the data, you need to process the data for paging on the front end. According to your needs, you can sort, filter and other operations on the data.

  3. Page calculation: Calculate the total number of pages based on the amount of data displayed on each page and the total amount of data. Generally, you can use the following formula to calculate the total number of pages:
    totalPages = Math.ceil(totalCount / pageSize)

  4. Paging display:Display the paging navigation bar and data list on the page. You can use HTML and CSS to build a paginated navigation bar, which usually includes buttons for previous page, next page, home page, and last page.

  5. Paging logic:Implement the click event of the paging button and the corresponding logic. When the user clicks the previous page or next page button, the corresponding data is calculated and displayed based on the current page number and the total page number.

  6. Data rendering:According to the current page number and the amount of data displayed on each page, intercept the data that needs to be displayed on the current page from the total data, and render it onto the page.

  7. Optional functions:According to actual needs, you can add some additional functions, such as jumping to a specified page, displaying the current page number, etc.

It should be noted that the above idea provides a general paging implementation idea, and the specific implementation method also depends on the front-end framework or library you use. Different frameworks or libraries may have their own paging components or methods, which can be selected and used according to specific circumstances.

1.2. Understand its concept 

In front-end development, universal paging is a common feature that can divide a large amount of data into multiple pages for display, providing a better user experience. Here are some front-end theoretical concepts related to universal paging:

  1. Data Source: refers to the source that provides paging data. It can be the data returned by the back-end interface, or it can be local data, cached data, etc. The data source is the basis of the entire paging function.

  2. Total Count: indicates the total number of records in the data source, that is, the total number of paging data. The total number of records is used to calculate the total number of pages and is displayed to the user in the paging navigation bar.

  3. Current Page: indicates the number of pages currently displayed. Users can view different data pages by switching the current page number. The current page number usually starts from 1 and goes up to the total page number.

  4. Total Pages:The total number of pages calculated based on the total number of records and the number of records displayed per page. The total number of pages is used to determine the number of page numbers in the paging navigation bar, and to determine whether the previous page and next page buttons need to be displayed.

  5. Number of records per page (Page Size):Specify the number of records to be displayed on each page. By setting the number of records per page, you can control the amount of data displayed on each paginated page.

  6. Pagination Navigation:Usually displayed on the page as a set of links or buttons to help users navigate to different data pages. The paging navigation bar can include operation buttons such as previous page, next page, home page, and last page, as well as information showing the current page number and the total number of pages.

  7. Pagination Logic:According to the user's operation, such as clicking the previous page and next page buttons, calculate the corresponding page number and obtain the corresponding page number from the data source data, and perform rendering and display logic.

  8. Data Rendering:The process of displaying the acquired paging data on the front-end page. You can use HTML, CSS and other technologies to build data display templates, and fill paginated data into the templates.

The above concepts are the theoretical basis commonly used when implementing universal paging functions. Understanding these concepts can help you better understand and implement front-end paging functions. The exact implementation will vary depending on the front-end framework or library used.

 1.3. Understand its benefits

Universal pagination has many benefits in front-end development, here are some of the main benefits:

  1. Provide better user experience:The universal paging function can display large amounts of data in pages, allowing users to browse and navigate data more conveniently, improving the user experience.

  2. Speed ​​up page loading:When the amount of data is large, loading all the data into the front-end page at once may cause the page to load slowly or even crash. By loading data in pages, the amount of data loaded each time can be reduced and the page loading speed can be improved.

  3. Save network bandwidth: Loading data in pages can reduce the amount of data transmitted over the network and reduce the consumption of network bandwidth, which is especially important when the mobile network environment is unstable. .

  4. Simplify data processing logic:By displaying data in pages, complex data operation logic can be dispersed into each page, making the front-end code clearer and easier to maintain.

  5. Improve system performance:Displaying data in pages can reduce the burden on the back-end server and reduce the pressure on data query and transmission, thereby improving system performance and response speed.

  6. Customizability and flexibility:Universal paging functions are usually customizable. The amount of data displayed on each page, the style of the paging navigation bar, and layout, etc. to suit the requirements of different projects.

All in all, the universal paging function can improve user experience, reduce data transmission burden, and improve system performance. It is a very useful feature in front-end development. By properly using the paging function, you can better manage and display large amounts of data and improve user satisfaction with the application.

2. Optimize pagebean

There are several main reasons for optimizing PageBean:

  1. Improving performance:When the amount of data is large, the PageBean object may contain a large amount of data, and in some scenarios, it is not necessary to load all the data into the PageBean. . By optimizing PageBean, memory usage and data loading time can be reduced, thereby improving system performance.

  2. Reduce network transmission: Obtaining the PageBean object from the backend requires network transmission, and network transmission is a relatively slow operation. By optimizing PageBean, you can reduce the amount of data transmitted, reduce bandwidth usage, and shorten data transmission time.

  3. Simplified data structure:Sometimes PageBean may contain some unnecessary fields or redundant data, which may have no practical use for front-end display or business logic. By optimizing PageBean, the data structure can be streamlined, retaining only the required fields, and improving the readability and maintainability of the code.

  4. Improve code reusability:If PageBean is designed properly, it can be reused multiple times in different scenarios. By optimizing PageBean, you can increase its reusability, reduce repetitive code writing, and improve development efficiency.

  5. Increase scalability:By optimizing PageBean, you can consider adding some extension fields or methods to cope with possible future demand changes or function expansion. This can reduce subsequent development and maintenance costs.

  6. Precisely control data loading:By optimizing PageBean, precise data loading strategies can be achieved, such as on-demand loading, lazy loading, etc. This can avoid performance degradation or lagging caused by loading too much data at once.

In short, optimizing PageBean can improve the performance and maintainability of the system, reduce network transmission and memory usage, and provide a more flexible and accurate data loading strategy. Through reasonable design and optimization, PageBean can be more adapted to actual business needs and development scenarios.

The code before optimization is as follows:

package com.junlinyi.util;
 
/**
 * 分页工具类
 *
 */
public class PageBean {
 
	private int page = 1;// 页码
 
	private int rows = 10;// 页大小
 
	private int total = 0;// 总记录数
 
	private boolean pagination = true;// 是否分页
 
	public PageBean() {
		super();
	}
 
	public int getPage() {
		return page;
	}
 
	public void setPage(int page) {
		this.page = page;
	}
 
	public int getRows() {
		return rows;
	}
 
	public void setRows(int rows) {
		this.rows = rows;
	}
 
	public int getTotal() {
		return total;
	}
 
	public void setTotal(int total) {
		this.total = total;
	}
 
	public void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}
 
	public boolean isPagination() {
		return pagination;
	}
 
	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}
 
	/**
	 * 获得起始记录的下标
	 * 
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}
 
	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
	}
 
}

After optimization, the code is as follows:

package com.junlinyi.utils;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * 分页工具类
 *增加一个属性url,保留上一次发送的请求地址
	 * 	增加一个属性paramMap,保留上一次发送的请求携带的参数
	 * 			req.getParameterMap();
	 * 增加一个最大页的方法
	 * 增加一个下一页的方法
	 * 增加一个上一页的方法
	 * 初始化pegebean的方法
 */
public class PageBean {

	private int page = 1;// 页码

	private int rows = 10;// 页大小

	private int total = 0;// 总记录数

	// 上一次查询的url
	private String url;
	// 上一次查询所携带的查询条件
	private Map<String, String[]> parameterMap = new HashMap<String, String[]>();

	// 对pagebean进行初始化
	public void setRequest(HttpServletRequest req) {
		// 初始化jsp页面传递过来的当前页
		this.setPage(req.getParameter("page"));
		// 初始化jsp页面传递过来的页大小
		this.setRows(req.getParameter("rows"));
		// 初始化jsp页面传递过来是否分页
		this.setPagination(req.getParameter("pagination"));
		// 保留上一次的查询请求
		this.setUrl(req.getRequestURL().toString());
		// 保留上一次的查询条件
		this.setParameterMap(req.getParameterMap());
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Map<String, String[]> getParameterMap() {
		return parameterMap;
	}

	public void setParameterMap(Map<String, String[]> parameterMap) {
		this.parameterMap = parameterMap;
	}

	private void setPagination(String pagination) {
		// 只有填写了false字符串,才代表不分页
		this.setPagination(!"false".equals(pagination));
	}

	private void setRows(String rows) {
		if (StringUtils.isNotBlank(rows))
			this.setRows(Integer.valueOf(rows));
	}

	private void setPage(String page) {
		if (StringUtils.isNotBlank(page))
			this.setPage(Integer.valueOf(page));
	}

	private boolean pagination = true;// 是否分页

	public PageBean() {
		super();
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}

	public boolean isPagination() {
		return pagination;
	}

	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}

	/**
	 * 获得起始记录的下标
	 * 
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}

	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
	}

	// 上一页
	public int getPrevPage() {
		return this.page > 1 ? this.page - 1 : this.page;
	}

	// 下一页
	public int getNextPage() {
		return this.page < this.getMaxPage() ? this.page + 1 : this.page;
	}

	// 最大页
	public int getMaxPage() {
		return this.total % this.rows == 0 ? this.total / this.rows : (this.total / this.rows) + 1;
	}

}

 3. Develop custom jsp tags for pagination

3.1 Create PageTag class

package com.junlinyi.tag;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import com.junlinyi.utils.PageBean;

/**
 * @author 君临沂
 * 
 */
public class PageTage extends BodyTagSupport {
    private PageBean pageBean;



    public PageBean getPageBean() {
        return pageBean;
    }

    public void setPageBean(PageBean pageBean) {
        this.pageBean = pageBean;
    }

    @Override
    public int doStartTag() throws JspException {
        JspWriter out = pageContext.getOut();
        try {
            out.print(toHTML());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return SKIP_BODY;
    }

    private String toHTML() {
        StringBuilder sb = new StringBuilder();

//        这里拼接的是一个上一次发送的请求以及携带的参数,唯一改变的就是页码
        sb.append("<form id='pageBeanForm' action='"+pageBean.getUrl()+"' method='post'>");
        sb.append("<input type='hidden' name='methodName' value='list'>");
        sb.append("<input type='hidden' name='page'>");
//        重要设置拼接操作,将上一次请求参数携带到下一次
        Map<String, String[]> paMap = pageBean.getParameterMap();
        if(paMap !=null && paMap.size()>0){
            Set<Map.Entry<String, String[]>> entrySet = paMap.entrySet();
            for (Map.Entry<String, String[]> entry : entrySet) {
                for (String val : entry.getValue()) {
                    if(!"page".equals(entry.getKey())){
                        sb.append("<input type='hidden' name='"+entry.getKey()+"' value='"+val+"'>");
                    }
                }
            }
        }
        sb.append("</form>");


        int page = pageBean.getPage();
        int max = pageBean.getMaxPage();
        int before = page > 4 ? 4 : page-1;
        int after = 10 - 1 - before;
        after = page+after > max ? max-page : after;
//        disabled
        boolean startFlag = page == 1;
        boolean endFlag = max == page;

//        拼接分页条
        sb.append("<ul class='pagination'>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage(1)'>首页</a></li>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getPrevPage()+")'>&lt;</a></li>");

//        代表了当前页的前4页
        for (int i = before; i > 0 ; i--) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page-i)+")'>"+(page-i)+"</a></li>");
        }

        sb.append("<li class='page-item active'><a class='page-link' href='javascript:gotoPage("+pageBean.getPage()+")'>"+pageBean.getPage()+"</a></li>");

//        代表了当前页的后5页
        for (int i = 1; i <= after; i++) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page+i)+")'>"+(page+i)+"</a></li>");
        }

        sb.append("<li class='page-item "+(endFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getNextPage()+")'>&gt;</a></li>");
        sb.append("<li class='page-item "+(endFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getMaxPage()+")'>尾页</a></li>");
        sb.append("<li class='page-item go-input'><b>到第</b><input class='page-link' type='text' id='skipPage' name='' /><b>页</b></li>");
        sb.append("<li class='page-item go'><a class='page-link' href='javascript:skipPage()'>确定</a></li>");
        sb.append("<li class='page-item'><b>共"+pageBean.getTotal()+"条</b></li>");
        sb.append("</ul>");

//        拼接分页的js代码
        sb.append("<script type='text/javascript'>");
        sb.append("function gotoPage(page) {");
        sb.append("document.getElementById('pageBeanForm').page.value = page;");
        sb.append("document.getElementById('pageBeanForm').submit();");
        sb.append("}");
        sb.append("function skipPage() {");
        sb.append("var page = document.getElementById('skipPage').value;");
        sb.append("if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > "+max+") {");
        sb.append("alert('请输入1~N的数字');");
        sb.append("return;");
        sb.append("}");
        sb.append("gotoPage(page);");
        sb.append("}");
        sb.append("</script>");

        return sb.toString();
    }
}

3.2 Create configuration file (tld) file

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
	<tlib-version>1.0</tlib-version>
	<jsp-version>1.2</jsp-version>
	<short-name>Simple Tags</short-name>
	<uri>http://www/JunLinYi/com</uri>	
   
	<tag>
        <name>page</name>
        <tag-class>com.junlinyi.tag.PageTage</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>pageBean</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
	
</taglib>

3.3BookList

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www/JunLinYi/com" prefix="z"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link
	href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
	rel="stylesheet">
<script
	src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍列表</title>
<style type="text/css">
.page-item input {
	padding: 0;
	width: 40px;
	height: 100%;
	text-align: center;
	margin: 0 6px;
}

.page-item input, .page-item b {
	line-height: 38px;
	float: left;
	font-weight: 400;
}

.page-item.go-input {
	margin: 0 10px;
}
</style>
</head>
<body>
	${pageBean }
	<form class="form-inline"
		action="${pageContext.request.contextPath }/book.action" method="post">
		<div class="form-group mb-2">
			<input type="text" class="form-control-plaintext" name="bname"
				placeholder="请输入书籍名称">
		</div>
		<button type="submit" class="btn btn-primary mb-2">查询</button>
	</form>

	<table class="table table-striped bg-success">
		<thead>
			<tr>
				<th scope="col">书籍ID</th>
				<th scope="col">书籍名</th>
				<th scope="col">价格</th>
			</tr>
		</thead>
		<tbody>
		<c:forEach items="${book }" var="b">
			<tr>
				<td>${b.bid }</td>
				<td>${b.bname }</td>
				<td>${b.price }</td>
			</tr>
		</c:forEach>
		</tbody>
	</table>

	<z:page pageBean="${pageBean }"></z:page>


</body>
</html>

3.4BookServlet

package com.junlinyi.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.junlinyi.dao.BookDao;
import com.junlinyi.entity.Book;
import com.junlinyi.utils.PageBean;
/**
 * 
 * @author: 君临沂
 *
 */

@WebServlet("/book.action")
public class BookServlet extends HttpServlet {
		@Override
		protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
			this.doPost(req, resp);
		}
		
		@SuppressWarnings("unused")
		@Override
		protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//			String bname = req.getParameter("bname");
				map包含了浏览器传递到后台的所有参数键值对
//				Map<String, String[]> map = req.getParameterMap();
				浏览器请求的地址
//				String url = req.getRequestURL().toString();
			
			PageBean pb=new PageBean();
			pb.setRequest(req);
			BookDao bd=new BookDao();
			Book bk=new Book();
			bk.setBname(req.getParameter("bname"));
			 try {
				List<Book> book = bd.list2(bk, pb);
				req.setAttribute("book",book);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			req.setAttribute("pageBean",pb);
			req.getRequestDispatcher("bookList.jsp").forward(req, resp);
		}
}

3.5 filter

When outputting pages or searching books, we will find that garbled characters may occur. At this time, we only need to add a filter.

package com.junlinyi.utils;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 过滤器
 * 中文乱码处理
 * 
 */
@WebFilter("*.action")
public class EncodingFiter implements Filter {

	private String encoding = "UTF-8";// 默认字符集

	public EncodingFiter() {
		super();
	}

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;

		// 中文处理必须放到 chain.doFilter(request, response)方法前面
		res.setContentType("text/html;charset=" + this.encoding);
		if (req.getMethod().equalsIgnoreCase("post")) {
			req.setCharacterEncoding(this.encoding);
		} else {
			Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
			Set set = map.keySet();// 取出所有参数名
			Iterator it = set.iterator();
			while (it.hasNext()) {
				String name = (String) it.next();
				String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
				for (int i = 0; i < values.length; i++) {
					values[i] = new String(values[i].getBytes("ISO-8859-1"),
							this.encoding);
				}
			}
		}

		chain.doFilter(request, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
		if (null != s && !s.trim().equals("")) {
			this.encoding = s.trim();
		}
	}

}

plan :


Finally, the detailed explanation of paging (front-end) ends here. I wish everyone a smooth journey on the way to coding!

Thank you everyone for watching!! ! ! ! !

 

Guess you like

Origin blog.csdn.net/m0_74915426/article/details/131453100