JavaWeb笔记Day8------会话技术与JSP

会话技术

会话

一次会话包含多次请求和响应

  • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止

功能

在一次会话的范围内的多次请求间,共享数据

方式

  1. 客户端会话技术:Cookie

  2. 服务器端会话技术:Session

概念:

客户端会话技术,将数据保存到客户端

使用步骤:

  1. 创建Cookie对象,绑定数据
new Cookie(String name, String value)
  1. 发送Cookie对象
response.addCookie(Cookie cookie)
  1. 获取Cookie,拿到数据
Cookie[] request.getCookies()

实现原理

基于响应头set-cookie和请求头cookie实现

image-20220309153815493

Cookie细节

  1. 一次可不可以发送多个cookie?
  • 可以
  • 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
  1. cookie在浏览器中保存多长时间?

    • 默认情况下,当浏览器关闭后,Cookie数据被销毁
  2. 持久化存储:

    • setMaxAge(int seconds)

      • 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效

      • 负数:默认值

      • 零:删除cookie信息

      1. cookie能不能存中文?
    • 在tomcat 8 之前 cookie中不能直接存储中文数据。

    • 需要将中文数据转码---一般采用URL编码(%E3)

    • 在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析

  3. cookie共享问题

    1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享

      • 默认情况下cookie不能共享
      • setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
        • 如果要共享,则可以将path设置为"/"
    2. 不同的tomcat服务器间cookie共享问题

      • setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享

      • setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享

Cookie特点

  1. cookie存储数据在客户端浏览器
  2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)

Cookie作用

  1. cookie一般用于存出少量的不太敏感的数据

  2. 在不登录的情况下,完成服务器对客户端的身份识别

案例

需求
  1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。

  2. 如果不是第一次访问,则提示:欢迎回来,您上次访问的时间为:显示时间字符串

分析
  1. 可以采用Cookie来完成
  2. 在服务器中的Servlet判断是否有一个名为lastTime的cookie
  3. 有:不是第一次访问
    1. 响应数据:欢迎回来,您上次访问时间为:2018年6月10日11:50:20
    2. 写回Cookie:lastTime=2018年6月10日11:50:01
  4. 没有:是第一次访问
    1. 响应数据:您好,欢迎您首次访问
    2. 写回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的。

image-20220310223931013

细节

  1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个

    • 默认情况下,不是

    • 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存

      Cookie c=new Cookie("JSESSIONID",session.getId());
      c.setMaxAge(60*60);
      response.addCookie(c);
  2. 客户端不关闭,服务器关闭后,两次获取的session是否是同一个

    • 不是同一个,但要确保数据不丢失
      • session的钝化:
        • 在服务器正常关闭之前,将session对象系列化到硬盘上
      • session的活化:
        • 在服务器启动后,将session文件转化为内存中的session对象即可
  3. session的失效时间

    1. 服务器关闭

    2. session对象调用invalidate()。

    3. session默认失效时间是30分钟

      <!--选择性配置修改-->
      <session-config>
      <session-timeout>30</session-timeout>
      </session-config>

特点

  1. session用于存储一次会话的多次请求的数据,存在服务器端
  2. session可以存储任意类型,任意大小的数据

session与cookie的区别

  1. session存储数据在服务器端,Cookie在客户端
  2. session没有数据大小限制,Cookie有
  3. session数据安全,Cookie相对于不安全

案例

  1. 需求:

    1. 访问带有验证码的登录页面login.jsp
    2. 用户输入用户名,密码以及验证码。
      • 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
      • 如果验证码输入有误,跳转登录页面,提示:验证码错误
      • 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
  2. 分析:

    image-20220310235137499

  3. 代码:

    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
    image-20220309220244375

脚本

  • 概念: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 异常对象

image-20220309225310898

指令

作用

用于配置JSP页面,导入资源文件

格式

<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ...%>

分类

  1. page:配置JSP页面的

    • contentType:等同于response.setContentType()
      1. 设置响应体的mime类型以及字符集
      2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需设置pageEncoding属性设置当前页面的字符集)
    • import:导包
    • errorPage:当前页面发生一次后,会自动跳转到指定的错误页面
    • iserrorPag:标识当前页面是否是错误页面。
      • true:是,可以使用内置对象exception
      • false:否,默认值。不可以使用内置对象exception
  2. include:页面包含的。导入页面的资源文件

    <%@include file="top.jsp">
  3. taglib:导入资源

    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    • prefix:前缀,自定义的

    注:关于idea中http://java.sun.com/jsp/jstl/core“报红,解决方案参考

    1. 解决idea中http://java.sun.com/jsp/jstl/core“红色异常_居贝比的博客-CSDN博客
    2. IntelliJ IDEA 怎么导入JSTL标签_百度知道 (baidu.com)

注释

  1. html注释:

    <!--只能注释HTML代码片段-->
  2. jsp注释:推荐使用

    <%--
    可以注释所有
    --%>

MVC开发模式

Jsp演变历史

image-20220311222557157

MVC

  1. M:Model,模型
    • 完成具体的业务操作,如:查询数据库,封装对象
  2. V:View,视图
    • 展示数据
  3. C:Controller,控制器。Servlet
    • 获取用户的输入
    • 调用模型
    • 将数据交给视图进行展示

优点

  1. 耦合性低,方便维护,可以利于分工协作
  2. 重用性高

缺点

  1. 使得项目架构变得复杂,对开发人员要求高

EL表达式

概念

Expression Language

作用

替换和简化jsp页面中Java代码的编写

语法

${表达式}

注意

  • jsp默认支持el表达式的。如果要忽略el表达式

    1. 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
    2. ${表达式}:忽略当前这个el表达式

使用

  1. 运算符

    1. 算术运算符:+ - * /(div)%(mod)
    2. 比较运算符:> < >= <= == !=
    3. 逻辑运算符:&&(and)||(or) !(not)
    4. 空运算符:empty
      • 功能:用于判断字符串,集合,数组对象是否为null并且长度是否为0
      • $
      • {not empty str}:表示判断字符串,集合,数组对象是否不为null,并且长度>0
  2. 获取值

    1. el表达式只能从域对象获取值

    2. 语法:

      1. {域名称,键名}:从指定域中获取指定的值

        1. 域名称:

          域名 对象
          pageScope pageContext
          requestScope request
          sessionScope session

        | applicationScope | application(ServletContext) |

        1. 举例:在request域中存储了name=张三

        2. 获取:$

      2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止

      3. 获取对象,List集合,Map集合的值

        1. 对象:$
          • 本质上会去调用对象的getter方法
        2. List集合:$
        3. Map集合:
          • $
          • $
    3. 隐式对象:

      • el表达式中有11个隐式对象

      • pageContext:

        • 获取jsp其他八个内置对象

          ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL

概念

JavaServer Pages Tags Library JSP标准标准库

  • 是由Apache组织提供的开源的免费的jsp标签 <标签>

作用

用于简化和替换jsp页面上的Java代码

使用步骤

  1. 导入jstl相关jar包

    参考:jsp - How to install JSTL? The absolute uri: http://java.sun.com/jstl/core cannot be resolved - Stack Overflow

  2. 引入标签库:taglib指令:<%@ taglib%>

  3. 使用标签

常用的JSTL标签

  1. if:相当于Java代码的if语句

    1. 属性:
      • test 必须属性,接受boolean表达式
        • 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
        • 一般情况下,test属性值会结合el表达式一起使用
    2. 注意:c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
  2. choose:相当于Java代码的switch语句

  3. 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>

三层架构

  1. 界面层(表示层):用户看的界面。用户可以通过界面上的组件和访问器进行交互
  2. 业务逻辑层:处理业务逻辑的。
  3. 数据访问层:操作数据存储文件的 image-20220315000223221

案例

需求

用户信息的增删改查操作

设计

  1. 技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtils+Tomcat

  2. 数据库设计:

    #使用数据库
    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)
    );
  3. 开发:

    1. 环境搭建
      1. 创建数据库环境
      2. 创建项目,导入需要的jar包
    2. 编码
  4. 测试

  5. 部署运维

简单功能

列表查询

分析

image-20220315005147048

代码
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>&nbsp;
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a>
</td>
</tr>
</c:forEach>
</table >

登录

分析
  1. 调整页面,加入验证码功能(验证码实现扩展:Java滑动验证码的原理与实现_Lark丶的博客-CSDN博客_滑动验证码的原理

  2. 代码实现

代码
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)

注:拓展参考:

  1. Java滑动验证码的原理与实现_Lark丶的博客-CSDN博客_滑动验证码的原理
  2. Java实现字符验证码、运算验证码_Lark丶的博客-CSDN博客_java运算验证码
/**
* 验证码
*/
@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>

添加联系人

分析

image-20220316000837127

代码
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>

删除联系人

分析

image-20220318193740203

代码
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>&nbsp;
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a>
</td>
</tr>
</c:forEach>
</table >

修改信息

分析

image-20220318200525102

代码
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>&nbsp;
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a>
</td>
</tr>
</c:forEach>
</table >
</form>

复杂功能

删除选中

分析

image-20220318210325046

代码
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>&nbsp;
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a>
</td>
</tr>
</c:forEach>
</table >
</form>

分页查询

好处
  1. 减少服务器开销

  2. 提升用户体验

分析

image-20220319233300887

image-20220319235948681

代码
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>&nbsp;
<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">&laquo;</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">&raquo;</span>
</a>
</li>
<span style="font-size:25px;margin-left:5px">
共${pageBean.totalCount}条记录,共${pageBean.totalPage}页
</span>
</ul>
</nav>
</div>

复杂条件查询

分析

image-20220321011712519

代码
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">&laquo;</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">&raquo;</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 中国大陆许可协议进行许可。

posted @   灰之魔女伊蕾娜  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开