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>