JavaWeb笔记Day8------会话技术与JSP
会话技术
会话
一次会话包含多次请求和响应
- 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
功能
在一次会话的范围内的多次请求间,共享数据
方式
-
客户端会话技术:Cookie
-
服务器端会话技术:Session
Cookie
概念:
客户端会话技术,将数据保存到客户端
使用步骤:
- 创建Cookie对象,绑定数据
new Cookie(String name, String value)
- 发送Cookie对象
response.addCookie(Cookie cookie)
- 获取Cookie,拿到数据
Cookie[] request.getCookies()
实现原理
基于响应头set-cookie和请求头cookie实现
Cookie细节
- 一次可不可以发送多个cookie?
- 可以
- 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
-
cookie在浏览器中保存多长时间?
- 默认情况下,当浏览器关闭后,Cookie数据被销毁
-
持久化存储:
-
setMaxAge(int seconds)
-
正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
-
负数:默认值
-
零:删除cookie信息
- cookie能不能存中文?
-
-
在tomcat 8 之前 cookie中不能直接存储中文数据。
-
需要将中文数据转码---一般采用URL编码(%E3)
-
在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
-
-
cookie共享问题
-
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享
- 默认情况下cookie不能共享
- setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
- 如果要共享,则可以将path设置为"/"
-
不同的tomcat服务器间cookie共享问题
-
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
-
setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
-
-
Cookie特点
- cookie存储数据在客户端浏览器
- 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)
Cookie作用
-
cookie一般用于存出少量的不太敏感的数据
-
在不登录的情况下,完成服务器对客户端的身份识别
案例
需求
-
访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
-
如果不是第一次访问,则提示:欢迎回来,您上次访问的时间为:显示时间字符串
分析
- 可以采用Cookie来完成
- 在服务器中的Servlet判断是否有一个名为lastTime的cookie
- 有:不是第一次访问
- 响应数据:欢迎回来,您上次访问时间为:2018年6月10日11:50:20
- 写回Cookie:lastTime=2018年6月10日11:50:01
- 没有:是第一次访问
- 响应数据:您好,欢迎您首次访问
- 写回Cookie:lastTime=2018年6月10日11:50:01
代码
package Cookie; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLDecoder; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.SimpleFormatter; @WebServlet(name = "CookieTest", value = "/CookieTest") public class CookieTest extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应的消息体的数据格式以及编码 response.setContentType("text/html;charset=utf-8"); //1.获取所有的Cookie Cookie[] cookies=request.getCookies(); boolean flag=false;//没有Cookie为lastTime //2.遍历Cookie if (cookies!=null && cookies.length>0){ for (Cookie cookie:cookies){ //3.获取Cookie的名称 String name=cookie.getName(); //4.判断名称是否是lastTime if ("lastTime".equals(name)){ //有该Cookie,不是第一次访问 flag=true;//有lastTime的Cookie //提取上次访问的时间 String value=cookie.getValue(); //设置Cookie的value值 //获取当前时间的字符串,重新设置Cookie的value值,重新发送Cookie Date date=new Date(); SimpleDateFormat formatter=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String dateString=formatter.format(date); //URL编码 dateString= URLEncoder.encode(dateString,"utf-8"); cookie.setValue(dateString); //设置Cookie的有效期为一个月 cookie.setMaxAge(60*60*24*30); response.addCookie(cookie); //响应数据 //获取Cookie的value,时间 //URL解码 value= URLDecoder.decode(value,"utf-8"); System.out.println("上次访问的时间:"+value); response.getWriter().write("<h1>欢迎回来,您上次访问的时间为:"+value+"</h1>"); break; } } } if(cookies==null || cookies.length==0 || !flag){ //没有,第一次访问 //设置Cookie的value值 //获取当前时间的字符串,重新设置Cookie的value值,重新发送Cookie Date date=new Date(); SimpleDateFormat formatter=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String dateString=formatter.format(date); //URL编码 dateString= URLEncoder.encode(dateString,"utf-8"); Cookie cookie=new Cookie("lastTime",dateString); //设置Cookie的有效期为一个月 cookie.setMaxAge(60*60*24*30); response.addCookie(cookie); response.getWriter().write("<h1>欢迎您第一次访问</h1>"); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
Session
概念
服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HTTPSession
方法
//获取HttpSession对象 HTTPSession session=request.getSession(); //使用HttpSession对象 Object getAttribute(String name); void setAttribute(String name,Object value); void removeAttribute(String name);
原理
Session的实现是依赖于Cookie的。
细节
-
当客户端关闭后,服务器不关闭,两次获取session是否为同一个
-
默认情况下,不是
-
如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
Cookie c=new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
-
-
客户端不关闭,服务器关闭后,两次获取的session是否是同一个
- 不是同一个,但要确保数据不丢失
- session的钝化:
- 在服务器正常关闭之前,将session对象系列化到硬盘上
- session的活化:
- 在服务器启动后,将session文件转化为内存中的session对象即可
- session的钝化:
- 不是同一个,但要确保数据不丢失
-
session的失效时间
-
服务器关闭
-
session对象调用invalidate()。
-
session默认失效时间是30分钟
<!--选择性配置修改--> <session-config> <session-timeout>30</session-timeout> </session-config>
-
特点
- session用于存储一次会话的多次请求的数据,存在服务器端
- session可以存储任意类型,任意大小的数据
session与cookie的区别
- session存储数据在服务器端,Cookie在客户端
- session没有数据大小限制,Cookie有
- session数据安全,Cookie相对于不安全
案例
-
需求:
- 访问带有验证码的登录页面login.jsp
- 用户输入用户名,密码以及验证码。
- 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
- 如果验证码输入有误,跳转登录页面,提示:验证码错误
- 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
-
分析:
-
代码:
User类
package web.test.domain; /** * 用户的实体类 */ public class User { private int id; private String username; private String password; private String checkCode; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } public String getCheckCode() { return checkCode; } public void setCheckCode(String checkCode) { this.checkCode = checkCode; } } loginServlet.java
package web.servlet; import jakarta.servlet.*; import jakarta.servlet.http.*; import jakarta.servlet.annotation.*; import org.apache.commons.beanutils.BeanUtils; import web.test.dao.UserDao; import web.test.domain.User; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.Map; @WebServlet(name = "loginServlet", value = "/loginServlet") public class loginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.设置request编码 request.setCharacterEncoding("utf-8"); //2.获取参数Map Map<String, String[]> parameterMap = request.getParameterMap(); //获取生成的验证码 HttpSession session = request.getSession(); String checkCodeInSession = (String) session.getAttribute("checkCode"); //删除session中的验证码 session.removeAttribute("checkCode"); //判断验证码是否正确 //忽略大小写比较 if (checkCodeInSession!=null && checkCodeInSession.equalsIgnoreCase(parameterMap.get("checkCode")[0])) { //判断用户名和密码是否正确 User loginUser = new User(); //3.1使用BeanUtils封装 try { BeanUtils.populate(loginUser, parameterMap); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } ////4.调用UserDao的login方法 UserDao userDao = new UserDao(); User user = userDao.login(loginUser); //5.判断user if (user != null) { //登录成功 //存储信息,用户信息 session.setAttribute("user", parameterMap.get("username")[0]); //重定向到success.jsp response.sendRedirect(request.getContextPath()+"/success.jsp"); }else { //登录失败 //存储信息到request域 request.setAttribute("login_error", "用户名或密码错误"); //转发到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); } }else { //验证码错误 //存储提示信息到request域中 request.setAttribute("cc_error", "验证码错误"); //转发到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); } } } login.jsp
<%-- Created by IntelliJ IDEA. User: admin Date: 2022-03-11 Time: 17:17 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>login</title> <script> window.onload = function () { document.getElementById("img").onclick = function () { document.getElementById("img").src = "/StudyJavaWeb00/CheckCodeServlet?time=" + new Date().getTime(); } } </script> <style> div{ color: red; } </style> </head> <body> <form action="/StudyJavaWeb00/loginServlet" method="post"> <table> <tr> <td>用户名</td> <td><input type="text" name="username"/></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password"/></td> </tr> <tr> <td>验证码</td> <td><input type="text" name="checkCode"/></td> </tr> <tr> <td colspan="2"><img id="img" src="/StudyJavaWeb00/CheckCodeServlet"/></td> <tr> <td colspan="2"><input type="submit" value="登录"/></td> </tr> </table> </form> <div><%=request.getAttribute("cc_error") == null ? "" : request.getAttribute("cc_error")%></div> <div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error")%>></div> </body> </html> success.jsp
<%-- Created by IntelliJ IDEA. User: admin Date: 2022-03-11 Time: 19:56 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1><%=request.getSession().getAttribute("user")%>,欢迎您</h1> </body> </html>
JSP
概念
Java Server Pages:Java服务器端页面
- 可以理解为:一个特殊的页面,其中既可以指定定义HTML标签,又可以定义Java代码
- 用于简化书写
原理
- JSP本质上就是一个Servlet
脚本
-
概念:JSP定义Java代码的方式
-
种类:
<% 代码%>:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么 <%! 代码%>:定义的Java代码,在jsp转换后的Java类的成员位置 <%=代码%>:定义的Java代码,会输出到页面上。输出语句中可以定义什么
内置对象
在jsp页面中不需要获取和创建,可以直接使用的对象
jsp一共有9个内置对象
变量名 | 真实类型 | 作用 |
---|---|---|
pageContext | PageContext | 当前页面共享数据,还可以获取其他八个内置对象 |
request | HttpServletRequest | 一次请求访问的多个资源(转发) |
session | HttpSession | 一次会话的多个请求间 |
application | ServletContext | 所有用户间共享数据 |
response | HttpServletResponse | 响应对象 |
page | Object | 当前页面(Servlet)的对象 this |
out | JspWriter | 输出对象,数据输出到页面上(字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似。(注:①在Tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,在找out缓冲区数据。②response.getWriter()数据输出永远在out.write()之前)) |
config | ServletConfig | Servlet的配置对象 |
exception | Throwable | 异常对象 |
指令
作用
用于配置JSP页面,导入资源文件
格式
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ...%>
分类
-
page:配置JSP页面的
- contentType:等同于response.setContentType()
- 设置响应体的mime类型以及字符集
- 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需设置pageEncoding属性设置当前页面的字符集)
- import:导包
- errorPage:当前页面发生一次后,会自动跳转到指定的错误页面
- iserrorPag:标识当前页面是否是错误页面。
- true:是,可以使用内置对象exception
- false:否,默认值。不可以使用内置对象exception
- contentType:等同于response.setContentType()
-
include:页面包含的。导入页面的资源文件
<%@include file="top.jsp"> -
taglib:导入资源
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> - prefix:前缀,自定义的
注:关于idea中http://java.sun.com/jsp/jstl/core“报红,解决方案参考
注释
-
html注释:
<!--只能注释HTML代码片段--> -
jsp注释:推荐使用
<%-- 可以注释所有 --%>
MVC开发模式
Jsp演变历史
MVC
- M:Model,模型
- 完成具体的业务操作,如:查询数据库,封装对象
- V:View,视图
- 展示数据
- C:Controller,控制器。Servlet
- 获取用户的输入
- 调用模型
- 将数据交给视图进行展示
优点
- 耦合性低,方便维护,可以利于分工协作
- 重用性高
缺点
- 使得项目架构变得复杂,对开发人员要求高
EL表达式
概念
Expression Language
作用
替换和简化jsp页面中Java代码的编写
语法
${表达式}
注意
-
jsp默认支持el表达式的。如果要忽略el表达式
- 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
- ${表达式}:忽略当前这个el表达式
使用
-
运算符
- 算术运算符:+ - * /(div)%(mod)
- 比较运算符:> < >= <= == !=
- 逻辑运算符:&&(and)||(or) !(not)
- 空运算符:empty
- 功能:用于判断字符串,集合,数组对象是否为null并且长度是否为0
- $
- {not empty str}:表示判断字符串,集合,数组对象是否不为null,并且长度>0
-
获取值
-
el表达式只能从域对象获取值
-
语法:
-
{域名称,键名}:从指定域中获取指定的值
-
域名称:
域名 对象 pageScope pageContext requestScope request sessionScope session
| applicationScope | application(ServletContext) |
-
举例:在request域中存储了name=张三
-
获取:$
-
-
${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止
-
获取对象,List集合,Map集合的值
- 对象:$
- 本质上会去调用对象的getter方法
- List集合:$
- Map集合:
- $
- $
- 对象:$
-
-
隐式对象:
-
el表达式中有11个隐式对象
-
pageContext:
-
获取jsp其他八个内置对象
${pageContext.request.contextPath}:动态获取虚拟目录
-
-
-
JSTL
概念
JavaServer Pages Tags Library JSP标准标准库
- 是由Apache组织提供的开源的免费的jsp标签 <标签>
作用
用于简化和替换jsp页面上的Java代码
使用步骤
-
导入jstl相关jar包
-
引入标签库:taglib指令:<%@ taglib%>
-
使用标签
常用的JSTL标签
-
if:相当于Java代码的if语句
- 属性:
- test 必须属性,接受boolean表达式
- 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
- 一般情况下,test属性值会结合el表达式一起使用
- test 必须属性,接受boolean表达式
- 注意:c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
- 属性:
-
choose:相当于Java代码的switch语句
-
foreach:相当于Java代码的for语句
-
完成重复操作
- 属性:
- begin:开始值
- end:结束值
- var:临时变量
- step:步长
- varStatus:循环状态对象
- index:容器中元素的索引,从0开始
- count:循环次数,从1开始
- 属性:
-
遍历容器
- items:容器对象
- var:容器中元素的临时变量
- varStatus:循环状态对象
- index:容器中元素的索引,从0开始
- count:循环次数,从1开始
-
练习
需求
在request域中有一个存有User对象的List集合。需要使用jstl+el将list集合数据展示到jsp页面的表格table中
代码
<%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page import="web.test.jstl.User" %> <%@ page import="java.util.Date" %><%-- Created by IntelliJ IDEA. User: admin Date: 2022-03-14 Time: 2:12 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Test</title> </head> <body> <% List list = new ArrayList(); list.add(new User("张三",23,new Date())); list.add(new User("李四",24,new Date())); list.add(new User("王五",25,new Date())); request.setAttribute("list",list); %> <table border="1" width="500" align="center"> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> <th>生日</th> </tr> <%-- 数据行--%> <c:forEach items="${list}" var="user" varStatus="s"> <c:if test="${s.count%2==0}"> <tr bgcolor="blue"> <td>${s.count}</td> <td>${user.name}</td> <td>${user.age}</td> <td>${user.birStr}</td> </tr> </c:if> <c:if test="${s.count%2!=0}"> <tr bgcolor="red"> <td>${s.count}</td> <td>${user.name}</td> <td>${user.age}</td> <td>${user.birStr}</td> </tr> </c:if> </c:forEach> </table> </body> </html>
三层架构
- 界面层(表示层):用户看的界面。用户可以通过界面上的组件和访问器进行交互
- 业务逻辑层:处理业务逻辑的。
- 数据访问层:操作数据存储文件的
案例
需求
用户信息的增删改查操作
设计
-
技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtils+Tomcat
-
数据库设计:
#使用数据库 USE Test; CREATE TABLE user( #建表 id INT primary key auto_increment, name VARCHAR(20) not null, gender VARCHAR(5), age INT, address VARCHAR(32), qq VARCHAR(20), email VARCHAR(50) ); -
开发:
- 环境搭建
- 创建数据库环境
- 创建项目,导入需要的jar包
- 编码
- 环境搭建
-
测试
-
部署运维
简单功能
列表查询
分析
代码
userListServlet
package web.servlet; import domain.User; import jakarta.servlet.*; import jakarta.servlet.http.*; import jakarta.servlet.annotation.*; import service.UserService; import service.impl.UserServiceImpl; import java.io.IOException; import java.util.List; @WebServlet(name = "userListServlet", value = "/userListServlet") public class userListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. 调用UserService完成查询 UserService service = new UserServiceImpl(); List<User> users = service.findAll(); //2.将list存入request域 request.setAttribute("users", users); //3.转发到list.jsp request.getRequestDispatcher("/list.jsp").forward(request, response); } }
UserServiceImpl
package service.impl; import dao.UserDao; import dao.impl.UserDaoImpl; import domain.Login; import domain.PageBean; import domain.User; import service.UserService; import java.util.List; public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public List<User> findAll() { //调用Dao完成查询 return dao.findAll(); } }
JDBCUtils
package util; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; /** * JDBC工具类,使用Durid连接池 */ public class JDBCUtils { private static DataSource ds; static{ //1.加载配置文件 Properties pro = new Properties(); //使用ClassLoader加载配置文件,获取字节输入流 InputStream is=JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"); try { pro.load(is); //2.初始化连接池对象 ds= DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接池对象 * @return */ public static DataSource getDataSource(){ return ds; } /** * 获取连接Connection对象 * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } }
UserDaoImpl
package dao.impl; import dao.UserDao; import domain.Login; import domain.User; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import util.JDBCUtils; import java.util.List; public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public List<User> findAll() { //操作数据库 //1. 定义sql String sql="select * from user"; List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class)); return users; } }
User
package domain; public class User { private int id; private String name; private String gender; private int age; private String address; private String qq; private String email; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", gender='" + gender + '\'' + ", age=" + age + ", address='" + address + '\'' + ", qq='" + qq + '\'' + ", email='" + email + '\'' + '}'; } }
Index.jsp
<div align="center"> <a href="${pageContext.request.contextPath}/UserListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息 </a> </div>
list.jsp
<table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox" id="firstCb"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <%-- 循环遍历数据库中的数据,以表格形式获取(套路) --%> <c:forEach items="${users}" var="user" varStatus="s"> <tr> <td><input type="checkbox" value="${user.id}" id="" name="uid"></td> <td>${s.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td> <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a> </td> </tr> </c:forEach> </table >
登录
分析
-
调整页面,加入验证码功能(验证码实现扩展:Java滑动验证码的原理与实现_Lark丶的博客-CSDN博客_滑动验证码的原理)
-
报错:
-
rg.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1,actual 0 1
-
java.lang.ClassNotFoundException: org.apache.commons.collections.FastHashMap
-
-
-
代码实现
代码
loginServlet
@WebServlet(name = "loginServlet", value = "/loginServlet") public class loginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.设置编码 request.setCharacterEncoding("utf-8"); //2.获取数据 //2.1获取用户填写的验证码 String verifycode = request.getParameter("verifycode"); Map<String,String[]> map =request.getParameterMap(); //4.验证码校验(常用套路) HttpSession session = request.getSession(); String CHECKCODE_SERVER = (String) session.getAttribute("CHECKCODE_SERVER"); //验证码校验成功后,需要清除验证码(确保一次性) session.removeAttribute("CHECKCODE_SERVER"); if(verifycode ==null || !verifycode.equalsIgnoreCase(CHECKCODE_SERVER)){ //验证码错误 //提示信息 request.setAttribute("login_msg","验证码错误"); //跳转到登录页面 request.getRequestDispatcher("/login.jsp").forward(request,response); return; } //4.封装User对象 Login login = new Login(); try { BeanUtils.populate(login,map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //5.调用service方法 UserService service = new UserServiceImpl(); Login login_user = service.login(login); //6.判断是否登录成功 if(login_user != null){ //登录成功 //将用户信息存入session session.setAttribute("login_user",login_user); //跳转到首页 response.sendRedirect(request.getContextPath()+"/index.jsp"); }else{ //登录失败 //提示信息 request.setAttribute("login_msg","用户名或者密码错误"); //跳转到登录页面 request.getRequestDispatcher("/login.jsp").forward(request,response); } } }
字符验证码(CheckCode)
注:拓展参考:
/** * 验证码 */ @WebServlet("/CheckCodeServlet") public class CheckCodeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { //服务器通知浏览器不要缓存 response.setHeader("pragma","no-cache"); response.setHeader("cache-control","no-cache"); response.setHeader("expires","0"); //在内存中创建一个长80,宽30的图片,默认黑色背景 //参数一:长 //参数二:宽 //参数三:颜色 int width = 80; int height = 30; BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //获取画笔 Graphics g = image.getGraphics(); //设置画笔颜色为灰色 g.setColor(Color.GRAY); //填充图片 g.fillRect(0,0, width,height); //产生4个随机验证码,12Ey String checkCode = getCheckCode(); //将验证码放入HttpSession中 request.getSession().setAttribute("CHECKCODE_SERVER",checkCode); //设置画笔颜色为黄色 g.setColor(Color.YELLOW); //设置字体的小大 g.setFont(new Font("黑体",Font.BOLD,24)); //向图片上写入验证码 g.drawString(checkCode,15,25); //将内存中的图片输出到浏览器 //参数一:图片对象 //参数二:图片的格式,如PNG,JPG,GIF //参数三:图片输出到哪里去 ImageIO.write(image,"PNG",response.getOutputStream()); } /** * 产生4位随机字符串 */ private String getCheckCode() { String base = "0123456789ABCDEFGabcdefg"; int size = base.length(); Random r = new Random(); StringBuffer sb = new StringBuffer(); for(int i=1;i<=4;i++){ //产生0到size-1的随机值 int index = r.nextInt(size); //在base字符串中获取下标为index的字符 char c = base.charAt(index); //将c放入到StringBuffer中去 sb.append(c); } return sb.toString(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request,response); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public Login login(Login login) { return dao.login(login.getUsername(),login.getPassword()); } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public Login login(String username, String password) { String sql="select * from login where username=? and password=?"; try { Login login=template.queryForObject(sql,new BeanPropertyRowMapper<Login>(Login.class),username,password); return login; }catch (EmptyResultDataAccessException e){ return null; } } }
Login
package domain; public class Login { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "Login{" + "username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }
login.jsp
<script type="text/javascript"> //切换验证码 function refreshCode(){ //1. 获取验证码图片对象 let vcode=document.getElementById("vcode"); //2.设置其src属性,加时间戳 vcode.src="${pageContext.request.contextPath}/CheckCodeServlet?time="+new Date().getTime(); } </script> <div class="form-inline"> <label for="vcode">验证码:</label> <input type="text" name="verifycode" class="form-control" id="verifycode" placeholder="请输入验证码" style="width: 120px;"/> <a href="javascript:refreshCode()"><img src="${pageContext.request.contextPath}/CheckCodeServlet" title="看不清点击刷新" id="vcode"/></a> </div> <!-- 出错显示的信息框 --> <strong>${login_msg==null?"":login_msg}</strong>
添加联系人
分析
代码
addUserServlet
@WebServlet(name = "addUserServlet", value = "/addUserServlet") public class addUserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.设置编码 request.setCharacterEncoding("utf-8"); //2.获取参数 Map<String, String[]> parameterMap = request.getParameterMap(); //3.封装对象 User user = new User(); try { BeanUtils.populate(user, parameterMap); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //4.调用service保存 UserService service = new UserServiceImpl(); service.addUser(user); //5.跳转到userListServlet response.sendRedirect(request.getContextPath() + "/findUserByPageServlet"); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public void addUser(User user) { dao.addUser(user); } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public void addUser(User user) { //1.定义SQL String sql="insert into user values(null,?,?,?,?,?,?)"; //2.执行SQL template.update(sql,user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail()); } }
add.jsp
<form action="${pageContext.request.contextPath}/addUserServlet" method="post"> ........ </form>
删除联系人
分析
代码
delUserServlet
@WebServlet(name = "delUserServlet", value = "/delUserServlet") public class delUserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取id String id = request.getParameter("id"); //2.调用service删除 UserService service = new UserServiceImpl(); service.deleteUser(id); //3.跳转到查询所有Servlet response.sendRedirect(request.getContextPath()+"/findUserByPageServlet"); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public void deleteUser(String id) { dao.deleteUser(Integer.parseInt(id)); } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public void deleteUser(int id) { //1.定义SQL String sql="delete from user where id=?"; template.update(sql,id); } }
list.jsp
<script> function deleteUser(id){ //用户安全提示 if (confirm("确定要删除吗?")){ //访问路径 location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id; } } </script> <table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox" id="firstCb"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <%-- 循环遍历数据库中的数据,以表格形式获取(套路) --%> <c:forEach items="${pageBean.list}" var="user" varStatus="s"> <tr> <td><input type="checkbox" value="${user.id}" id="" name="uid"></td> <td>${s.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td> <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a> </td> </tr> </c:forEach> </table >
修改信息
分析
代码
findUserServlet
@WebServlet(name = "findUserServlet", value = "/findUserServlet") public class findUserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取id String id = request.getParameter("id"); //2.调用service查询 UserService service = new UserServiceImpl(); User user=service.findUserById(id); //3.将user放入request域中 request.setAttribute("user", user); //4.转发到update.jsp request.getRequestDispatcher("/update.jsp").forward(request, response); } }
updateUserServlet
@WebServlet(name = "updateUserServlet", value = "/updateUserServlet") public class updateUserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //一条龙 //1.设置编码 request.setCharacterEncoding("utf-8"); //2.获取map Map<String, String[]> map=request.getParameterMap(); //3.封装对象 User user=new User(); try { BeanUtils.populate(user,map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //4.调用service修改 UserService service=new UserServiceImpl(); service.updateUser(user); //5.跳转到查询所有Servlet response.sendRedirect(request.getContextPath()+"/findUserByPageServlet"); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public void updateUser(User user) { dao.updateUser(user); } @Override public User findUserById(String id) { return dao.findUserById(Integer.parseInt(id)); } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public void updateUser(User user) { String sql="update user set name=?,gender=?,age=?,address=?,qq=?,email=? where id=?"; template.update(sql,user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail(),user.getId()); } @Override public User findUserById(int id) { String sql="select * from user where id=?"; User user=template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),id); return user; } }
update.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <!-- 指定字符集 --> <title>修改用户</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-2.1.0.min.js"></script> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container" style="width: 400px;"> <h3 style="text-align: center;">修改联系人</h3> <form action="${pageContext.request.contextPath}/updateUserServlet" method="post"> <%-- 隐藏域,提交id(重点)--%> <input type="hidden" name="id" value="${user.id}"> <div class="form-group"> <label for="name">姓名:</label> <input type="text" class="form-control" id="name" name="name" value="${user.name}" readonly="readonly" placeholder="请输入姓名" /> </div> <div class="form-group"> <label>性别:</label> <c:if test="${user.gender=='男'}"> <input type="radio" name="gender" value="男" checked />男 <input type="radio" name="gender" value="女" />女 </c:if> <c:if test="${user.gender=='女'}"> <input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" checked />女 </c:if> </div> <div class="form-group"> <label for="age">年龄:</label> <input type="text" class="form-control" id="age" value="${user.age}" name="age" placeholder="请输入年龄" /> </div> <div class="form-group"> <label for="address">籍贯:</label> <select name="address" id="address" class="form-control" > <c:if test="${user.address=='陕西'}"> <option value="陕西" selected>陕西</option> <option value="北京">北京</option> <option value="上海">上海</option> </c:if> <c:if test="${user.address=='北京'}"> <option value="陕西">陕西</option> <option value="北京" selected>北京</option> <option value="上海">上海</option> </c:if> <c:if test="${user.address=='上海'}"> <option value="陕西">陕西</option> <option value="北京">北京</option> <option value="上海" selected>上海</option> </c:if> </select> </div> <div class="form-group"> <label for="qq">QQ:</label> <input type="text" id="qq" value="${user.qq}" class="form-control" name="qq" placeholder="请输入QQ号码"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" id="email" class="form-control" value="${user.email}" name="email" placeholder="请输入邮箱地址"/> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="submit" value="提交" /> <input class="btn btn-default" type="reset" value="重置" /> <input class="btn btn-default" type="button" value="返回"/> </div> </form> </div> </body> </html>
list.jsp
<form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post"> <table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox" id="firstCb"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <%-- 循环遍历数据库中的数据,以表格形式获取(套路) --%> <c:forEach items="${pageBean.list}" var="user" varStatus="s"> <tr> <td><input type="checkbox" value="${user.id}" id="" name="uid"></td> <td>${s.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td> <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a> </td> </tr> </c:forEach> </table > </form>
复杂功能
删除选中
分析
代码
delSelectedServlet
@WebServlet(name = "delSelectedServlet", value = "/delSelectedServlet") public class delSelectedServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取所有id String[] ids = request.getParameterValues("uid"); //2.调用service删除 UserService service = new UserServiceImpl(); service.delSelectedUser(ids); //3.跳转到查询所有的Servlet response.sendRedirect(request.getContextPath()+"/findUserByPageServlet"); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public void delSelectedUser(String[] ids) { if (ids != null && ids.length > 0) { //1.遍历数组 for (String id : ids) { //2.调用Dao完成删除 dao.deleteUser(Integer.parseInt(id)); } } } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public void deleteUser(int id) { //1.定义SQL String sql="delete from user where id=?"; template.update(sql,id); } }
list.jsp
<script> function deleteUser(id){ //用户安全提示 if (confirm("确定要删除吗?")){ //访问路径 location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id; } } window.onload=function(){ //给删除选中按钮添加点击事件 document.getElementById("delSelected").onclick=function(){ //用户安全提示 if (confirm("确定要删除选中条目吗?")){ let flag = false; //判断是否有选中条目 const cbs = document.getElementsByName("uid"); for(let i=0; i<cbs.length; i++){ //有一个条目被选中,就设置flag为true if(cbs[i].checked){ flag=true; break; } } if (flag){ //表单提交 document.getElementById("form").submit(); } } } //1.获取第一个cb document.getElementById("firstCb").onclick=function(){ //2.获取下边列表中所有的cb var cbs=document.getElementsByName("uid"); //3.遍历所有的cb for(var i=0;i<cbs.length;i++){ //4.设置cbs[i]的选中状态=firstCb.checked cbs[i].checked=this.checked; } } } </script> <div style="float: right;margin: 5px"> <a class="btn btn-primary" href="add.jsp">添加联系人</a></td> <a class="btn btn-primary" href="javascript:void (0);"id="delSelected">删除选中</a></td> </div> <form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post"> <table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox" id="firstCb"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <%-- 循环遍历数据库中的数据,以表格形式获取(套路) --%> <c:forEach items="${pageBean.list}" var="user" varStatus="s"> <tr> <td><input type="checkbox" value="${user.id}" id="" name="uid"></td> <td>${s.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td> <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a> </td> </tr> </c:forEach> </table > </form>
分页查询
好处
-
减少服务器开销
-
提升用户体验
分析
代码
findUserByPageServlet
@WebServlet(name = "findUserByPageServlet", value = "/findUserByPageServlet") public class findUserByPageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取参数 String currentPage=request.getParameter("currentPage");//当前页码 String rows=request.getParameter("rows");//每页显示的条数 if (currentPage==null||"".equals(currentPage) || Integer.parseInt(currentPage)<=0){ currentPage="1"; } if (rows==null||"".equals(rows)) { rows="5"; } //2.调用service查询 UserService service=new UserServiceImpl(); PageBean<User> pageBean=service.findUserByPage(currentPage,rows); //3.将pageBean放入request域中 request.setAttribute("pageBean",pageBean); //4.转发到list.jsp request.getRequestDispatcher("/list.jsp").forward(request,response); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public PageBean<User> findUserByPage(String currentPage, String rows) { //创建空的PageBean对象 PageBean<User> pb = new PageBean<User>(); //设置参数 pb.setCurrentPage(Integer.parseInt(currentPage)); pb.setRows(Integer.parseInt(rows)); //调用Dao查询总记录数 int totalCount = dao.findTotalCount(); pb.setTotalCount(totalCount); //计算总页码 int totalPage = totalCount % pb.getRows() == 0 ? totalCount / pb.getRows() : totalCount / pb.getRows() + 1; pb.setTotalPage(totalPage); if (pb.getCurrentPage() >= totalPage) { pb.setCurrentPage(totalPage); } //调用Dao查询List集合 //计算开始的记录索引 int start = (pb.getCurrentPage() - 1) * pb.getRows(); List<User> list = dao.findByPage(start, pb.getRows()); pb.setList(list); return pb; } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public int findTotalCount() { String sql="select count(*) from user"; return template.queryForObject(sql,Integer.class); } @Override public List<User> findByPage(int start, int rows) { String sql="select * from user limit ?,?"; List<User> users=template.query(sql,new BeanPropertyRowMapper<User>(User.class),start,rows); return users; } }
PageBean
package domain; import java.util.List; /** * 分页对象 */ public class PageBean<T> { private int totalCount; // 总记录数 private int totalPage ; // 总页码 private List<T> list ; // 每页的数据 private int currentPage ; //当前页码 private int rows;//每页显示的记录数 public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } @Override public String toString() { return "PageBean{" + "totalCount=" + totalCount + ", totalPage=" + totalPage + ", list=" + list + ", currentPage=" + currentPage + ", rows=" + rows + '}'; } }
list.jsp
<form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post"> <table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox" id="firstCb"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <%-- 循环遍历数据库中的数据,以表格形式获取(套路) --%> <c:forEach items="${pageBean.list}" var="user" varStatus="s"> <tr> <td><input type="checkbox" value="${user.id}" id="" name="uid"></td> <td>${s.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td> <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a> </td> </tr> </c:forEach> </table > </form> <div> <nav aria-label="Page navigation"> <ul class="pagination"> <c:if test="${pageBean.currentPage==1}"> <li class="disabled"> </c:if> <c:if test="${pageBean.currentPage!=1}"> <li> </c:if> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pageBean.currentPage-1}&rows=5" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <c:forEach begin="1" end="${pageBean.totalPage}" var="i"> <c:if test="${pageBean.currentPage==i}"> <li class="active"><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5">${i}</a></li> </c:if> <c:if test="${pageBean.currentPage!=i}"> <li><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5">${i}</a></li> </c:if> </c:forEach> <c:if test="${pageBean.currentPage!=pageBean.totalPage}"> <li> </c:if> <c:if test="${pageBean.currentPage==pageBean.totalPage}"> <li class="disabled"> </c:if> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pageBean.currentPage+1}&rows=5" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <span style="font-size:25px;margin-left:5px"> 共${pageBean.totalCount}条记录,共${pageBean.totalPage}页 </span> </ul> </nav> </div>
复杂条件查询
分析
代码
findUserByPageServlet
@WebServlet(name = "findUserByPageServlet", value = "/findUserByPageServlet") public class findUserByPageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); //1.获取参数 String currentPage=request.getParameter("currentPage");//当前页码 String rows=request.getParameter("rows");//每页显示的条数 if (currentPage==null||"".equals(currentPage) || Integer.parseInt(currentPage)<=0){ currentPage="1"; } if (rows==null||"".equals(rows)) { rows="5"; } //获取条件查询参数 Map<String,String[]> condition=request.getParameterMap(); //2.调用service查询 UserService service=new UserServiceImpl(); PageBean<User> pageBean=service.findUserByPage(currentPage,rows,condition); // try{ // PageBean<User> pageBean=service.findUserByPage(currentPage,rows,condition); // //3.将pageBean放入request域中 // request.setAttribute("pageBean",pageBean); // //将查询条件存入request域中 // request.setAttribute("condition",condition); // // // //4.转发到list.jsp // request.getRequestDispatcher("/list.jsp").forward(request,response); // }catch (Exception e){ // request.getRequestDispatcher("/error.jsp").forward(request,response); // } //3.将pageBean放入request域中 request.setAttribute("pageBean",pageBean); //将查询条件存入request域中 request.setAttribute("condition",condition); //4.转发到list.jsp request.getRequestDispatcher("/list.jsp").forward(request,response); } }
UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao dao =new UserDaoImpl(); @Override public PageBean<User> findUserByPage(String currentPage, String rows, Map<String, String[]> condition) { //创建空的PageBean对象 PageBean<User> pb = new PageBean<User>(); //设置参数 pb.setCurrentPage(Integer.parseInt(currentPage)); pb.setRows(Integer.parseInt(rows)); //调用Dao查询总记录数 int totalCount = dao.findTotalCount(condition); pb.setTotalCount(totalCount); //计算总页码 int totalPage = totalCount % pb.getRows() == 0 ? totalCount / pb.getRows() : totalCount / pb.getRows() + 1; pb.setTotalPage(totalPage); if (pb.getCurrentPage() >= totalPage) { pb.setCurrentPage(totalPage); } //调用Dao查询List集合 //计算开始的记录索引 int start = (pb.getCurrentPage() - 1) * pb.getRows(); List<User> list = dao.findByPage(start, pb.getRows(),condition); pb.setList(list); return pb; } }
UserDaoImpl
public class UserDaoImpl implements UserDao { private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); @Override public int findTotalCount(Map<String, String[]> condition) { //1.定义模板初始化sql String sql="select count(*) from user where 1=1"; StringBuilder sb=new StringBuilder(sql); //2.遍历map Set<String> keySet=condition.keySet(); //定义参数的集合 List<Object> params=new ArrayList<Object>(); for (String key:keySet){ //排除分页条件参数 if("currentPage".equals(key) || "rows".equals(key)){ continue; } //获取value String value=condition.get(key)[0]; //判断value是否有值 if(value!=null&&!"".equals(value)){ //有值 sb.append(" and "+key+" like ? "); params.add("%"+value+"%");//?条件的值 } } sql=sb.toString(); return template.queryForObject(sql,Integer.class,params.toArray()); } @Override public List<User> findByPage(int start, int rows, Map<String, String[]> condition) { String sql="select * from user where 1=1"; StringBuilder sb=new StringBuilder(sql); //2.遍历map Set<String> keySet=condition.keySet(); //定义参数的集合 List<Object> params=new ArrayList<Object>(); for (String key:keySet){ //排除分页条件参数 if("currentPage".equals(key) || "rows".equals(key)){ continue; } //获取value String value=condition.get(key)[0]; //判断value是否有值 if(value!=null&&!"".equals(value)){ //有值 sb.append(" and "+key+" like ? "); params.add("%"+value+"%");//?条件的值 } } //3.添加分页查询 sb.append(" limit ?,?"); //防止查询结果为空,报错 if (start<0){ start=0; } //添加分页查询参数值 params.add(start); params.add(rows); sql=sb.toString(); List<User> users=template.query(sql,new BeanPropertyRowMapper<User>(User.class),params.toArray()); return users; } }
list.jsp
<body> <div class="container"> <h3 style="text-align: center">用户信息列表</h3> <div style="float: left"> <form class="form-inline" action="${pageContext.request.contextPath}/findUserByPageServlet" method="post"> <div class="form-group"> <label for="exampleInputName2">姓名</label> <%-- 查询条件回显--%> <input type="text" name="name" value="${condition.name[0]}" class="form-control" id="exampleInputName2" placeholder="李四"> </div> <div class="form-group"> <label for="exampleInputEmail2">籍贯</label> <input type="text" name="address" value="${condition.address[0]}" class="form-control" id="exampleInputEmail2" placeholder="北京"> </div> <div class="form-group"> <label for="exampleInputEmail3">邮箱</label> <input type="text" name="email" value="${condition.email[0]}" class="form-control" id="exampleInputEmail3" placeholder=""> </div> <button type="submit" class="btn btn-default">查询</button> </form> </div> <div> <nav aria-label="Page navigation"> <ul class="pagination"> <c:if test="${pageBean.currentPage==1}"> <li class="disabled"> </c:if> <c:if test="${pageBean.currentPage!=1}"> <li> </c:if> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pageBean.currentPage-1}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <c:forEach begin="1" end="${pageBean.totalPage}" var="i"> <c:if test="${pageBean.currentPage==i}"> <li class="active"><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">${i}</a></li> </c:if> <c:if test="${pageBean.currentPage!=i}"> <li><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">${i}</a></li> </c:if> </c:forEach> <c:if test="${pageBean.currentPage!=pageBean.totalPage}"> <li> </c:if> <c:if test="${pageBean.currentPage==pageBean.totalPage}"> <li class="disabled"> </c:if> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pageBean.currentPage+1}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <span style="font-size:25px;margin-left:5px"> 共${pageBean.totalCount}条记录,共${pageBean.totalPage}页 </span> </ul> </nav> </div> </div> </body>
本文作者:灰之魔女伊蕾娜
本文链接:https://www.cnblogs.com/daohengdao/p/16033049.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)