一.理解分页思想
1.分页的实质
1.1(自我概述)
用最简单的话来说,就是在一个界面展示不了那么多数据时,通过一点手段将数据一部分一部分的加载出来,从而减少服务器的压力。并且使能够让服务器利用率提高!
1.2(专业术语)
分页思想是一种将大段文本或大量数据分成若干小块进行处理或显示的方法。它常用于各种计算机应用中,包括文本编辑器、浏览器、数据库查询等。
分页思想的主要目的是提高性能和用户体验。通过将大段文本或大量数据分成小块,可以减少一次性加载或处理的数据量,从而降低计算和传输的开销,并减少用户等待时间。此外,分页还可以提供更好的用户导航和浏览功能,使用户可以更方便地查看和操作数据。
在文本编辑器中,分页思想可以用于将长文本分成多个页面,以便用户能够逐页编辑和查看。在浏览器中,分页思想常用于将长网页内容分成多个可滚动的小块,以提供更好的浏览体验。在数据库查询中,分页思想可以用于将大量数据分成可翻页的结果集,以便用户可以分批次地浏览和获取数据。
分页思想的实现通常通过使用计数器、指针或索引来跟踪当前页和总页数,以及切换页面时的数据加载和更新。在用户界面中,常用的交互元素包括翻页按钮、滚动条或下拉列表,用于用户选择和导航不同的页面。
总之,分页思想是一种有效管理大量数据或大段文本的方法,可以提高性能、减少用户等待时间,并提供更好的用户体验和导航功能。
二.优化pageBean
1.添加一部分分页需要类
增加url保留上一次的请求地址
增加parammap 保留上一次请求的参数 req.get
增加一个最大页的方法
增加一个上一页的方法
增加一个下一页的方法
初始化 pagebean方法
并且根据自己的需求来进行操作
public String getUrl() { return url; } /** * @param url the url to set */ public void setUrl(String url) { this.url = url; } /** * @return the paramMap */ public Map<String, String[]> getParamMap() { return paramMap; } /** * @param paramMap the paramMap to set */ public void setParamMap(Map<String, String[]> paramMap) { this.paramMap = paramMap; } // 对pagebean进行初始化 public void setRequest(HttpServletRequest req) { // 初始化默认查询第几页数据 this.setPage(req.getParameter("page")); // 初始化的页大小 this.setRows(req.getParameter("rows")); // 初始化是否分页 this.setPagination(req.getParameter("pagination")); // 保留上一次url的查询请求 this.setUrl(req.getRequestURL().toString()); // 保留上一次的查询条件 this.setParameterMap(req.getParameterMap()); } public void setParameterMap(Map<String, String[]>paramMap) { this.paramMap = paramMap; } private void setPagination(String pagination) { // 只有填写了false字符串,才代表不分页 if (StringUtils.isNotBlank(pagination)) 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)); } // 上一页 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; } private String url; private Map<String, String[]>paramMap;
三.分页自定义jsp标签
1为什么要使用自定义分页jsp标签?
1.1自我理解
旧版本的分页是通过,HTML分页条 ,JavaScript,form表单,三者组成然后再通过"C"标签,进行实现功能,在实现的过程中,代码赋值,代码重复,并且有许多无用代码
而新版本的分页:是通过自定义jsp标签实现,在实现具体功能时代码简单明了,但是拼接复杂,容易出现错误,但是熟能生巧,而且在检查错误时能过很简单的找到!
1.2专业术语
1. 代码重用:自定义 JSP 标签可以将分页逻辑封装成一个可复用的组件,可以在多个页面或多个项目中重复利用,避免了重复编写相同的分页代码。
2. 简化开发:使用自定义分页 JSP 标签可以简化分页功能的开发过程。通过定义标签的属性,开发人员可以灵活地配置分页的样式、显示内容、数据源等,而无需手动编写复杂的分页逻辑。
3. 提高可读性和维护性:自定义分页 JSP 标签将分页相关的代码分离出来,使页面代码更加简洁清晰,易于理解和维护。同时,当需要修改分页逻辑时,只需修改标签的定义,而不需要修改每个页面的代码。
4. 增强可扩展性:自定义分页 JSP 标签可以根据实际需求进行扩展和定制。开发人员可以自定义标签的行为和样式,以满足不同的分页需求,例如添加自定义的翻页按钮、指定显示的页码数量等。
5. 提供更好的用户体验:自定义分页 JSP 标签可以提供更友好和灵活的分页功能。标签可以处理分页相关的请求和响应,在页面上显示正确的分页链接和页码,从而使用户可以方便地进行翻页操作,并提供更好的用户导航和浏览体验。
总而言之,使用自定义分页 JSP 标签可以提高开发效率,简化代码编写,增强可读性和可维护性,并提供更好的用户体验,是开发分页功能的有效手段。
2.实现自定义分页标签
1.首先建立连接类
在实现连接类时,要将我们需要拼接的html,js,地代码通过”append“方法追加,当然我们的样式是不可进行拼接的
package com.lz.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.servlet.jsp.tagext.JspTag; import com.lz.utils.PageBean; import java.io.IOException; import java.util.Map; import java.util.Set; /** * * @author lzzxq * */ public class PageTag 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.getParamMap(); 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() + ")'><</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() + ")'>></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(); } }
2.建立tid
注意:tag-class是:实现类路径;
<!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>/lz</uri> <tag> <name>page</name> <tag-class>com.lz.tag.PageTag</tag-class> <!--该标签有标签体--> <body-content>jsp</body-content> <attribute> <name>pageBean</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
3.导入jsp即可
<%@taglib prefix="z" uri="/lz"%>
3.servelt编写,过滤器
1.servelt代码实现
在servelt中将
String bname = request.getParameter("bname");
//map包含浏览器传输的所有键值对
Map<String, String[]>map=request.getParameterMap();
//请求的浏览器地址
String url = request.getRequestURI().toString();
替换成了
PageBean pageBean=new PageBean();
pageBean.setRequest(request);
从而减少代码量
package com.lz.servelt; import java.io.IOException; import java.util.List; import java.util.Map; 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.lz.dao.BookDao; import com.lz.entity.Book; import com.lz.utils.PageBean; @WebServlet("/book.action") public class BookServelt extends HttpServlet { private static final String UNUSED = "unused"; /** * */ private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @SuppressWarnings(UNUSED) protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PageBean pageBean=new PageBean(); pageBean.setRequest(request); BookDao bd=new BookDao(); Book bk=new Book(); bk.setBname(request.getParameter("bname")); try { List<Book>book= bd.list(bk, pageBean); // System.out.println(book); request.setAttribute("book",book); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } request.setAttribute("pageBean",pageBean); request.getRequestDispatcher("bookList.jsp").forward(request, response); } }
2.处理乱码
中文乱码处理
@WebFilter("*.action")
package com.lz.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(); } } }
3.最终效果图:
四.debug使用
1.什么是debug?
Debug 是指在软件开发或故障排查过程中,通过追踪和分析程序的执行过程、变量的值以及程序输出,以发现和解决错误和异常的过程。
在软件开发过程中,debug 的主要目的是找出程序中的错误或异常,确保程序能够按照预期的方式运行。当程序出现 bug(错误)时,debug 可以帮助开发人员定位问题的原因,从而逐步排除 bug。
调试过程可以包括以下步骤:
1. 设置断点:在程序中设置断点,通常是在代码的特定位置,以使程序在该位置暂停执行,以便开发人员可以逐行检查程序的状态。
2. 执行程序:运行程序并触发特定的操作或输入,以使程序按预期方式运行。
3. 追踪变量值:在断点处,开发人员可以查看和监控程序中各个变量的值,以确保它们的值与预期相符。
4. 单步执行:逐行运行程序,观察程序的执行路径和状态变化,以及每个操作的结果。
5. 查看日志或输出:检查程序的输出、日志或错误消息,以获取与问题相关的信息。
6. 分析堆栈跟踪:当程序出现异常或错误时,查看堆栈跟踪信息,以确定错误发生的位置和调用关系。
7. 修复问题:根据调试过程中获得的信息,确定错误的原因,并进行相应的修复、调整或优化。
常用的调试工具包括集成开发环境(IDE)提供的调试器,例如在 Java 开发中的 Eclipse、IntelliJ IDEA,以及浏览器开发者工具提供的调试器等。
总之,debug 是一种追踪和分析程序执行过程的方法,用于发现和解决程序中的错误和异常,以确保程序按照预期的方式运行。
2.怎么使用?
1. 设置断点:在开发工具中选择要调试的代码位置,通常是在代码行号旁边点击或通过快捷键设置断点。断点是一个标记,它将使程序在运行到该位置时暂停执行。
2. 启动调试:运行程序,并启动调试模式。这通常可以通过点击调试按钮、使用快捷键或选择调试菜单中的选项来实现。启动调试模式后,程序将以调试模式运行,并在遇到断点时停止。
3. 逐行执行:通过单步执行,在每个断点处逐行执行代码。这可以使用“下一步”或“单步执行”按钮或使用快捷键进行操作。在每个步骤中,观察程序的执行路径、变量值和输出结果。
4. 查看变量值:在断点处,可以查看程序的变量值,以了解它们的当前状态。通常,在调试工具的变量窗口或监视窗口中,可以查看和监控各个变量的值。
5. 跟踪调用堆栈:如果程序出现异常或错误,可以查看调用堆栈跟踪信息,以了解错误发生的位置和调用关系。调试工具通常提供堆栈跟踪窗口或调用堆栈面板以便查看。
6. 添加条件断点:除了普通断点,还可以为断点添加条件,以便在满足特定条件时才触发断点。这可以提高调试的效率,以便在关键的代码路径上进行调试。
7. 观察输出和日志:查看程序的输出、日志或错误消息,以获取与问题相关的信息。这可以帮助了解程序的预期行为与实际行为之间的差异,并定位问题所在。
8. 修复问题:根据调试的结果和产生的错误信息,确定错误的原因,并进行相应的修复、调整或优化。
注意:不同的开发工具和环境可能会提供更多的调试功能和选项。建议在使用特定的调试工具之前,了解该工具的具体用法和功能。
总之,使用 debug 的关键是设置断点、逐行执行代码、观察变量和输出,以及利用调试工具提供的功能和选项。通过调试,可以更快地定位和解决程序中的错误和异常。