1. 会话技术
会话:一次会话中包含多次请求和响应
一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
功能:在一次会话的范围内的多次请求间共享数据
方式:
客户端会话技术:Cookie
服务器端会话技术:Session
1.1 Cookie
1.1.1 快速入门
概念:客户端会话技术,将数据保存在客户端
使用步骤:
创建Cookie对象,绑定数据
new Cookie(String name, String value)
发送Cookie对象
response.addCookie(Cookie cookie)
获取所有Cookie,拿到数据
Cookie[] getCookies()
package com.mark.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
/**
* Cookie快速入门
*/
@WebServlet("/cookieDemo1")
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建Cookie对象,绑定数据
Cookie cookie = new Cookie("msg", "HeHe");
//2.发送Cookie对象
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
@WebServlet("/cookieDemo2")
public class CookieDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//3.获取Cookie
Cookie[] cookies = request.getCookies();
//获取数据,遍历Cookies
if (cookies != null) {
for (Cookie c : cookies) {
String name = c.getName();
String value = c.getValue();
System.out.println(name + ": " + value);
}
}
/*
JSESSIONID: 5F22E6A6804B8AB0A5E144849D7E51C1
msg: HeHe
Webstorm-ec1c0726: 62f9d3ca-a2fa-4d36-aef6-9086650fec79
*/
}
}
1.1.2 实现原理分析
基于响应头set-cookie和请求体cookie实现
1.1.3 Cookie的细节
一次可否发送多个Cookie?
可以
创建多个Cookie对象,使用response调用多次addCookie()方法即可
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie1 = new Cookie("msg", "HeHe");
response.addCookie(cookie1);
Cookie cookie2 = new Cookie("name","mark");
response.addCookie(cookie2);
}
Cookie在浏览器中保存时间?
默认情况下当浏览器关闭后,Cookie数据被销毁
持久化存储:
setMaxAge(int seconds)
正数:将Cookie数据写到硬盘的文件中。持久化存储。正数代表存活时间。
负数:默认值
零:删除Cookie信息
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie1 = new Cookie("msg", "setMaxAge");
// cookie1.setMaxAge(300);//设置存活时间,将cookie持久化硬盘,300s后删除cookie文件
// cookie1.setMaxAge(-1);//设置存活时间,默认值
cookie1.setMaxAge(0);//设置存活时间,删除Cookie信息
response.addCookie(cookie1);
}
cookie能否存中文?
在tomcat8之前,Cookie不能直接存储中文数据
需要将中文数据转码---一般采用URL编码(%E3)
在tomcat8之后,Cookie支持中文数据。不支持特殊字符,建议使用URL编码存储
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie1 = new Cookie("msg", "你好");
response.addCookie(cookie1);
//msg: 你好
}
Cookie共享问题
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享
默认情况下Cookie不能共享
setPath(String path)
:设置Cookie的获取范围。默认情况下,会去设置当前的虚拟目录
cookie1.setPath("/");//在当前服务器的根目录下的所有项目可共享数据
不同的tomcat服务器间Cookie共享问题?
setDomain(String path)
:如果设置一级域名相同,那么多个服务器之间cookie可以共享
eg:setDomain(".baidu.com")
,那么tieba.baidu.com和news.baidu.com中cookie可以共享
1.1.4 Cookie的特点和作用
特点
Cookie存储数据在客户端浏览器
浏览器对于单个Cookie的大小有限制(4kb),以及对同一个域名下的总Cookie数量也有限制(20个)
作用:
cookie一般用来存储少量的不太敏感的数据
在不登陆的情况下,完成服务器对客户端的身份识别
1.1.5 案例:记住上次访问时间
需求:
- 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
分析:
可以采用Cookie完成
在服务器的Servlet中判断是否有一个名为lastTime的cooike
有:不是第一次访问
响应数据:欢迎回来,您上次访问时间为:
写回Cookie:lastTime=
没有:是第一次访问
响应数据:您好,欢迎您首次访问
写回Cookie:lastTime=
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
boolean flag = false;
//获取所有Cookie
Cookie[] cookies = request.getCookies();
//遍历cookie数组
if (cookies != null && cookies.length > 0) {
for (Cookie c : cookies) {
//获取cookie的名称
String name = c.getName();
if ("lastTime".equals(name)) {
flag = true;
//响应数据
String value = c.getValue();
value = URLDecoder.decode(value, "utf-8");
response.getWriter().write("欢迎回来,您上次访问时间为:" + value);
//设置cookie的value
//获取当前时间字符串,重新设置cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
str_date = URLEncoder.encode(str_date, "UTF-8");
c.setValue(str_date);
c.setMaxAge(60 * 60 * 24 * 30);
response.addCookie(c);
break;
}
}
}
if (cookies == null || cookies.length == 0 || flag == false) {
flag = true;
//设置cookie的value
//获取当前时间字符串,重新设置cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
str_date = URLEncoder.encode(str_date, "UTF-8");
Cookie c = new Cookie("lastTime", str_date);
response.addCookie(c);
response.getWriter().write("您好,欢迎您首次访问");
}
}
1.2 Session
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
1.2.1 快速入门
HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
步骤:
- 获取Session对象
存数据
获取Session对象
获取数据
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用Session共享对象
//1.获取session
HttpSession session = request.getSession();
//2.存数据
session.setAttribute("msg","hello session");
}
}
@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用Session共享对象
//1.获取session
HttpSession session = request.getSession();
//2.获取数据
Object msg = session.getAttribute("msg");
System.out.println(msg);
}
}
1.2.2 实现原理分析
Session的实现依赖于Cookie,通过请求头和响应头实现
1.2.3 Session细节
当客户端关闭后,服务器不关闭,两次获取Session是否为同一个?
默认情况下不是
//期望关闭客户端后,session也能相同:保存到客户端
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60*60);
客户端不关闭,服务器关闭,两次获取的Session是否为同一个?
不是同一个,但是要确保数据不丢失
Session的钝化
在服务器正常关闭之前,将Session对象序列化到硬盘上
Session的活化
在服务器启动后,将Session文件转化到内存中的Session对象即可
服务器会自动完成Session的钝化和活化,但是IDEA不会
Session什么时候被销毁?
服务器关闭
Session对象调用方法void invalidate()
Session的默认失效时间:30min(可以在Tomcat的配置文件D:\Tomcat\apache-tomcat-8.5.81\conf\web.xml中修改<session-config>标签的值)
1.2.4 Session的特点
Session用于存储一次会话的多次请求的数据,存在服务器端
可以在重定向时代替ServletContext
Session可以存储任意类型、任意大小的数据
Session与Cookie的区别
Session存储在服务器端,Cookie在客户端
Session没有数据大小限制,而Cookie有
Session数据安全,Cookie相对于较不安全
1.2.5 案例:登陆案例2.0
需求:
- 访问带有验证码的登录页面login.jsp
用户输入用户名,密码以及验证码。
如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
如果验证码输入有误,跳转登录页面,提示:验证码错误
如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
分析:
实现:
创建login.jsp登录页面
<%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/3
Time: 18:28
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 () {
var img = document.getElementById("checkCode");
img.onclick = function () {
img.src = "/LoginTest2/CheckCodeServlet?" + new Date().getTime();
}
var a = document.getElementById("change");
a.onclick = function () {
img.src = "/LoginTest2/CheckCodeServlet?" + new Date().getTime();
}
}
</script>
<style>
div {
color: red;
}
</style>
</head>
<body>
<form action="/LoginTest2/LoginServlet" method="post">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username" placeholder="请输入用户名"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password" placeholder="请输入密码"></td>
</tr>
<tr>
<td>验证码</td>
<td><input type="text" name="checkCode" placeholder="请输入验证码"></td>
</tr>
<tr>
<td><img id="checkCode" src="/LoginTest2/CheckCodeServlet"></td>
<td><a id="change" href="#">看不清,换一张</a></td>
</tr>
<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>
创建验证码img
package com.mark.web;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个对象,在内存中代表图片(验证码图片对象)
int width = 100;
int height = 50;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//美化图片
//填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0, 0, width, height);//填充颜色
//画边框
g.setColor(Color.BLUE);
g.drawRect(0, 0, width - 1, height - 1);
//写验证码
String str = "QWERTYUIOPASDGFHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789";
//生成随机角标
Random random = new Random();
StringBuilder sb=new StringBuilder();
for (int i = 1; i <= 4; i++) {
int index = random.nextInt(str.length());
//获取字符
char ch = str.charAt(index);
sb.append(ch);
g.drawString(ch + "", width / 5 * i, height / 2);
}
String checkCode_session = sb.toString();
request.getSession().setAttribute("checkCode_session",checkCode_session);
//干扰线
g.setColor(Color.GREEN);
for (int i = 1; i < 10; i++) {
//随机生成坐标点
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
g.drawLine(x1, y1, x2, y2);
}
//将图片输出到页面展示
ImageIO.write(image, "jpg", response.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
创建JavaBean
package com.mark.domain;
/**
* @ClassName User
* @Description TODO 用户的JavaBean(实体类)
* @Author Mark
* @Date 2022/7/31 20:44
* @Version 1.0
*/
public class User {
private int id;
private String username;
private String password;
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 + '\'' +
'}';
}
}
创建JDBC工具类
package com.mark.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;
/**
* @ClassName JDBCUtils
* @Description TODO JDBC工具类 使用Druid连接池
* @Author Mark
* @Date 2022/7/31 20:50
* @Version 1.0
*/
public class JDBCUtils {
private static DataSource ds;
static {
//加载配置文件
Properties pro =new Properties();
//使用classLoader加载配置文件,获取字节输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//初始化连接池
try {
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接池对象
public static DataSource getDataSource(){
return ds;
}
//获取连接Connection对象
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
操作数据库中User表
package com.mark.dao;
import com.mark.domain.User;
import com.mark.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @ClassName UserDao
* @Description TODO 操纵数据库中User表的类
* @Author Mark
* @Date 2022/7/31 20:48
* @Version 1.0
*/
public class UserDao {
//声明JDBCTemplate对象共用
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 登陆方法
* @param loginUser 只有用户名和密码
* @return User包含用户全部数据, 没有查询到,返回null
*/
public User login(User loginUser) {
try {
String sql = "select * from user where username=? and password = ?";
User user = template.queryForObject(sql,
new BeanPropertyRowMapper<User>(User.class),
loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (DataAccessException e) {
e.printStackTrace();//记录日志
return null;
}
}
}
创建登录LoginServlet
package com.mark.web;
import com.mark.dao.UserDao;
import com.mark.domain.User;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置request编码格式为utf-8
request.setCharacterEncoding("utf-8");
//获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
//创建User集合
User loginUser = new User();
//使用BeanUtils封装JavaBean
try {
BeanUtils.populate(loginUser, parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//获取页面输入的验证码
String checkCode = request.getParameter("checkCode");
//获取Session
HttpSession session = request.getSession();
//获取绘制的验证码
String checkCode_session = (String) session.getAttribute("checkCode_session");
//在获取后就移除session防止在登录后回退验证码还能生效
session.removeAttribute("checkCode_session");
//判断验证码输入是否正确
if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode)) {
//验证码正确
//查询数据库
UserDao dao = new UserDao();
User user = dao.login(loginUser);
if (user == null) {
//查询为空
//存储提示信息到request
request.setAttribute("login_error", "用户名或密码错误");
//转发到登录页面
request.getRequestDispatcher("/login.jsp").forward(request, response);
} else {
//登陆成功
session.setAttribute("user", user.getUsername());
response.sendRedirect(request.getContextPath() + "/success.jsp");
}
} else {
//验证码正确
//存储提示信息到request
request.setAttribute("cc_error", "验证码错误");
//转发到登录页面
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
2. JSP(了解即可)
概念:Java Server Pages:java服务器页面
可理解为一个特殊的页面,其中既可以直接定义HTML的标签,又可以编写Java代码
用于简化书写
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
System.out.println("hello jsp");
%>
<h1>hi~jsp</h1>
</body>
</html>
2.1 原理
JSP本质上就是Servlet
2.2 JSP的脚本
JSP的脚本:JSP定义Java代码的方式
<& 代码 &>
:定义的Java代码在service方法中。service中可以定义什么,该脚本就可以定义什么
<%
System.out.println("hello jsp");
int i = 5;//局部变量
%>
<&! 代码 &>
:定义的Java代码在jsp转换后的java类的成员位置。
<%!
int i = 3;//成员变量
%>
<&= 代码 &>
:定义的Java代码会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
<%= i + "hello" // 5hello 会打印局部变量%>
2.3 JSP的内置对象
在jsp页面中不需要获取和创建,直接可以使用的对象称为JSP的内置对象
一共有9个内置对象
request
response
out:字符输出流对象。可以将数据输出到页面上。和response.getWrite()类似
response.getWrite()和out.write()区别:前者永远会先于后者输出
在tomcat服务器真正给客户端浏览器做出响应前,会先找response缓冲区数据,再找out缓冲区数据
2.4 改造Cookie案例
<%@ page import="java.net.URLDecoder" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %><%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/2
Time: 19:39
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>
<%
boolean flag = false;
//获取所有Cookie
Cookie[] cookies = request.getCookies();
//遍历cookie数组
if (cookies != null && cookies.length > 0) {
for (Cookie c : cookies) {
//获取cookie的名称
String name = c.getName();
if ("lastTime".equals(name)) {
flag = true;
//响应数据
String value = c.getValue();
value = URLDecoder.decode(value, "utf-8");
%>
<h1>欢迎回来,您上次访问时间为:<%=value%>></h1>
<%
//设置cookie的value
//获取当前时间字符串,重新设置cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
str_date = URLEncoder.encode(str_date, "UTF-8");
c.setValue(str_date);
c.setMaxAge(60 * 60 * 24 * 30);
response.addCookie(c);
break;
}
}
}
if (cookies == null || cookies.length == 0 || flag == false) {
flag = true;
//设置cookie的value
//获取当前时间字符串,重新设置cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
str_date = URLEncoder.encode(str_date, "UTF-8");
Cookie c = new Cookie("lastTime", str_date);
response.addCookie(c);
%>
<h1>您好,欢迎您首次访问</h1>
<%
}
%>
</body>
</html>
2.5 JSP的指令
作用:用于配置JSP页面,导入资源文件
格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2%>
分类:
page:配置JSP页面
contentType:等同于response.setContentType()
设置响应体的mime类型以及字符集
设置当前JSP页面的编码(只能是高级的IDE才能生效,如果是低级工具,需要设置pageEncoding属性设置当前页面的字符集编码)
pageEcoding:设置当前JSP页面的编码
import:导包
errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
<%@ page errorPage="error.jsp" %>
isErrorPage:表示当前页面是否为错误页面。true/false
默认为false。当设置为true时就可以使用内置对象exception。可以将错误消息输出到日志文件中
include:在当前页面中导入项目中其他的页面
<%@ include file="top.jsp" %>
taglib:导入资源。一般用于导入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix:前缀(自定义)
2.6 JSP的注释
html注释:
<!-- -->
:只能注释html代码片段
JSP注释:推荐使用
<%-- --%>
:可注释所有
2.7 所有的内置对象
在JSP页面中不需要创建,直接使用的对象
变量名 | 真实类型 | 作用 |
---|---|---|
pageContext | PageContext | 当前页面共享数据,还可以获取其他八个内置对象 |
request | HttpServletRequest | 一次请求访问的对个资源(转发) |
session | HttpSession | 一次会话的多个请求间 |
application | ServletContext | 所有用户间共享数据 |
response | HttpServletResponse | 响应对象 |
page | Object | 当前页面(Servlet)的对象,可理解为this |
out | JspWriter | 输出对象,数据输出到页面上 |
config | ServletConfig | Servlet的配置对象 |
exception | Throwable | 异常对象 |
前四个:域对象。用于共享数据
3. MVC开发模式
3.1 jsp演变历史
- 早期只有Servlet,只能使用response输出标签数据,非常麻烦
后来有了JSP,简化可Servlet的开发。但如果过度使用JSP,在JSP中既写大量Java代码,又写HTML标签,会造成难以维护,难于分工协作,难于阅读
再后来,Java的Web开发,借鉴MVC开发模式,使得程序的设计更加合理性
3.2 MVC开发模式详解
MVC:将一个程序分为M、V、C三个部分。
M:Model,模型。JavaBean
完成具体的业务操作,如查询数据库,封装对象
V:View,视图。JSP
展示数据
C:Controller,控制器。Servlet
获取用户的输入
调用模型
将数据交给视图进行展示
3.3 MVC的优缺点
优点:
耦合性低,方便维护,利于分工协作
重用性高
缺点:
使得项目架构变得复杂,对开发人员要求很高
4. EL表达式
4.1 概述
概念:Expression Language 表达式语言
作用:替换和简化jsp页面中java代码的编写
语法:${表达式}
eg:${3 > 4}
输出false
注意:
JSP默认支持EL表达式
当在page指令中设置isELIgnored
为true时将不会解析此页面的EL表达式
在$前加反斜线将不会解析此EL表达式:\${3 > 4}
4.2 使用
运算
运算符:
算术运算符:+ - * /(div) %(mod)
比较运算符: > < >= <= == !=
逻辑运算符:&&(and) ||(or) !(not)
空运算符:empty
用于判断字符串、集合、数组对象是否为null并且长度是否为0
${empty list}
<%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/7
Time: 17:22
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>
${3 > 4}
\${3 > 4}
<hr>
<h3>算数运算符</h3>
${3 + 4}<br>
${3 / 4}<br>
${3 div 4}<br>
${3 % 4}<br>
${3 mod 4}<br>
<h3>比较运算符</h3>
${3 == 4}<br>
${3 != 4}<br>
<h3>逻辑运算符</h3>
${3 > 4 && 3 < 4}<br>
${3 > 4 and 3 < 4}<br>
<h3>空运算符</h3>
${3 > 4 && 3 < 4}<br>
${3 > 4 and 3 < 4}<br>
</body>
</html>
获取值
EL表达式只能从域对象中获取值
语法:
${域名称.键名}
:从指定域中获取指定键的值
域名称:
pageScope
--->pageContext
requestScope
--->request
sessionScope
--->session
applicationScope
--->application(ServletContext)
${键名}
:表示依次从最小的域中查找是否又该键对应的值,直到找到为止。
<%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/7
Time: 22:32
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取域中的数据</title>
</head>
<body>
<%
//在域中存储数据
request.setAttribute("name", "zhangsan");
session.setAttribute("age", 21);
session.setAttribute("name", "lisi");
%>
<h3>EL获取值</h3>
${requestScope.name}
${sessionScope.age}
${sessionScope.haha}<%--当为null时返回空字符串,不会影响页面布局--%>
${name}<%--zhangsan--%>
${sessionScope.name}<%--lisi--%>
</body>
</html>
获取对象、List集合、Map集合的值
对象:${域名称.键名.属性名}
本质上会去调用对象的getter方法
<%@ page import="com.mark.domain.User" %>
<%@ page import="java.util.Date" %><%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/7
Time: 22:57
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取数据</title>
</head>
<body>
<%
User user = new User();
user.setName("zhangsan");
user.setAge(21);
user.setBirthday(new Date());
request.setAttribute("u", user);
%>
<h3>获取对象的值</h3>
${requestScope.u}<br>
<%--
通过对象的属性获取
setter或getter方法,去掉set或get,再将剩余部分首字母变为小写,得到的内容称之为属性
setName ---> Name --->name
--%>
${requestScope.u.name}
${requestScope.u.age}
${requestScope.u.birthday}<br>
${requestScope.u.birthday.month}<%--7--%><br>
${requestScope.u.birStr}
<%-- 2022-08-07 23:14:37--%>
</body>
</html>
/**
* 逻辑视图
* @return
*/
public String getBirStr() {
//1.格式化日期
if (birthday != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//2.返回字符串
return sdf.format(birthday);
} else {
return "";
}
}
Map集合${域名称.键名.key名称}
<%@ page import="com.mark.domain.User" %>
<%@ page import="java.util.*" %><%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/7
Time: 23:20
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取集合数据</title>
</head>
<body>
<%
Map map = new HashMap<>();
map.put("name", "zhangsan");
map.put("gender", "male");
request.setAttribute("map", map);
%>
<h3>获取map值</h3>
${map.name}
${map.gender}<%--male--%>
${map["gender"]}<%--male--%>
</body>
</html>
空运算符的使用:
用于判断字符串、集合、数组对象是否为null并且长度是否为0
${empty str}
${not empty str}
:判断字符串、集合、数组对象是否不为null并且长度不为0
<h4>empty运算符</h4>
<%
// String str= "abc";
String str= null;
request.setAttribute("str",str);
%>
${empty str}
<%--false--%>
<%--true--%>
${not empty str}
<%--false--%>
隐式对象:
el表达式中有11个隐式对象
pageContext:
获取其他8个内置对象
${pageContext.request.contextPath}
5. JSTL标签
5.1 概述
概念:JavaServer Page Tag Library JSP标准标签库
是由Apache组织提供的开源的JSP标签
作用:用于简化和替换jsp页面的java代码
使用步骤:
导入JSTL相关jar包
引入标签库:taglib指令 <%@ taglib%>
使用标签
5.2 常用的JSTL标签
if:相当于Java的if语句
属性
test是必须属性 接收boolean表达式
如果表达式为ture,则显示if标签体内容,如果为false,则不显示标签体内容
如果有else情况,则可以再定义一个c:if
标签
choose:相当于Java的switch语句
完成数字编号对应星期几案例
- 在域中存储数字
使用choose标签取出数字(相当于switch)
使用when标签做数字判断(相当于case)
otherwise标签做其他情况声明(相当于default)
<%
request.setAttribute("number",3);
%>
<c:choose>
<c:when test="${number == 1}">星期一</c:when>
<c:when test="${number == 2}">星期二</c:when>
<c:when test="${number == 3}">星期三</c:when>
<c:when test="${number == 4}">星期四</c:when>
<c:when test="${number == 5}">星期五</c:when>
<c:when test="${number == 6}">星期六</c:when>
<c:when test="${number == 7}">星期日</c:when>
<c:otherwise>你输入的数字有误</c:otherwise>
</c:choose>
foreach:相当于Java的for循环语句
完成重复的操作
for(int i = 0;i < 10;i++){
...
}
属性:
begin:开始值(包含)
end:结束值(包含)
var:临时变量
stee:步长(临时遍历每次加几)
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
遍历容器
List<User> list = new ArrayList<>();
for(User user : list){
...
}
属性:
items:容器对象
var:容器中元素的临时变量
<c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
${i} ${s.index} ${s.count}<br>
</c:forEach>
<%--
1 1 1
3 3 2
5 5 3
7 7 4
9 9 5
--%>
<%--遍历容器--%>
<hr>
<%
List list=new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);
%>
<c:forEach items="${list}" var="str" varStatus="s" >
${s.index} ${s.count} ${str} <br>
</c:forEach>
<%--0 1 aaa--%>
<%--1 2 bbb--%>
<%--2 3 ccc--%>
5.3 小练习
需求:
在request域中有一个存有User对象的List集合
需要使用JSTL+EL将list集合数据展示到jsp页面的表格table中
<body>
<%
// User user =new User();
// List<User> list =new ArrayList<User>();
List<User> list = new ArrayList<>();
list.add(new User("zhangsan", 23, new Date()));
list.add(new User("lisi", 24, new Date()));
list.add(new User("wangwu", 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="red">
<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="green">
<td>${s.count}</td>
<td>${user.name}</td>
<td>${user.age}</td>
<td>${user.birStr}</td>
</tr>
</c:if>
</c:forEach>
</table>
</body>
6. 三层架构
三层架构:软件设计架构
界面层(表示层):用户看得到的界面,用户可以通过界面上的组件和服务器进行交互
业务逻辑层:处理业务逻辑的
数据访问层:操作数据存储文件
6.1 用户信息列表展示案例
需求:用户信息的增删改查操作
设计:
技术选型:Servlet+JSP+MySql+JDBCTemplate+Durid+BeanUtils+Tomcat
数据库设计:
create Database db4;
use db4;
create table user(
id int primary key auto_increment,
name varchar(20) not null,
gender varchar(6),
age int,
address varchar(32),
qq varchar(20),
email varchar(50)
);
开发:
环境搭建
创建数据库环境
创建项目,导入需要的jar包
编码
分析:
实现:
编写domain下的JavaBean
package com.mark.domain;
/**
* @ClassName User
* @Description TODO
* @Author Mark
* @Date 2022/8/14 18:12
* @Version 1.0
*/
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.html资源文件转化为index.jsp页面,修改超链接为${pageContext.request.contextPath}/userListServlet
<%--
Created by IntelliJ IDEA.
User: Mark
Date: 2022/8/14
Time: 17:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>首页</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
<div align="center">
<a
href="${pageContext.request.contextPath}/userListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息
</a>
</div>
</body>
</html>
在web目录下servlet包中创建UserListServlet,修改路径为/userListServlet
package com.mark.web.servlet;
import com.mark.domain.User;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.List;
@WebServlet("/userListServlet")
public class UserListServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在UserListServlet首先调用UserService完成查询
在service下创建接口UserService:用户管理的业务接口
package com.mark.service;
import com.mark.domain.User;
import java.util.List;
//用户管理的业务接口
public interface UserService {
/**
* 查询所有用户信息
* @return
*/
public List<User> findAll();
}
在service下的impl包下创建UserService的实现类UserServiceImpl,调用Dao完成查询
package com.mark.service.impl;
import com.mark.dao.UserDao;
import com.mark.dao.impl.UserDaoImpl;
import com.mark.domain.User;
import com.mark.service.UserService;
import java.util.List;
/**
* @ClassName UserServiceImpl
* @Description TODO
* @Author Mark
* @Date 2022/8/14 18:20
* @Version 1.0
*/
public class UserServiceImpl implements UserService {
@Override
public List<User> findAll() {
//调用Dao完成查询
return dao.findAll();
}
}
在dao下创建接口UserDao:用户操作的Dao
package com.mark.dao;
import com.mark.domain.User;
import java.util.List;
//用户操作的Dao
public interface UserDao {
public List<User> findAll();
}
在dao下的impl包下创建UserDao的实现类UserDaoImpl,使用JDBC操作数据库
package com.mark.dao.impl;
import com.mark.dao.UserDao;
import com.mark.domain.User;
import com.mark.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
/**
* @ClassName UserDaoImpl
* @Description TODO
* @Author Mark
* @Date 2022/8/14 18:22
* @Version 1.0
*/
public class UserDaoImpl implements UserDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public List<User> findAll() {
//使用JDBC操作数据库
}
}
在UserServiceImpl中创建UserDao对象,使用dao.findAll()查询所有数据
private UserDao dao = new UserDaoImpl();
@Override
public List<User> findAll() {
//调用Dao完成查询
return dao.findAll();
}
在Servlet中完成业务逻辑
//1.调用UserService完成查询
UserService service = new UserServiceImpl();
List<User> users = service.findAll();
//将List存入request域
request.setAttribute("users", users);
//转发到list.jsp页面
request.getRequestDispatcher("/list.jsp").forward(request,response);
完成UserDaoImpl中使用JDBC操作数据库
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public List<User> findAll() {
//使用JDBC操作数据库
//1.定义sql
String sql = "select * from user";
List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
return users;
}
将list.html资源文件转化为list.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>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>用户信息管理系统</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<style type="text/css">
td, th {
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h3 style="text-align: center">用户信息列表</h3>
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<c:forEach items="${requestScope.users}" var="user" varStatus="s">
<tr>
<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="update.html">修改</a> <a class="btn btn-default btn-sm"
href="">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="8" align="center"><a class="btn btn-primary" href="add.html">添加联系人</a></td>
</tr>
</table>
</div>
</body>
</html>
测试
部署运维
7. 综合练习
基于6.1案例完成
简单功能:
列表查询
登录
添加
删除
修改
复杂功能
删除选中
分页查询
复杂条件查询
7.1 登录功能
调整页面,加入验证码功能
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>管理员登录</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
//切换验证码
function refreshCode() {
//获取验证码的图片对象
var vcode = document.getElementById("vcode");
//设置其src属性,获取时间戳
vcode.src = "${pageContext.request.contextPath}/checkCodeServlet?time="+new Date().getTime();
}
</script>
</head>
<body>
<div class="container" style="width: 400px;">
<h3 style="text-align: center;">管理员登录</h3>
<form action="${pageContext.request.contextPath}/loginServlet" method="post">
<div class="form-group">
<label for="user">用户名:</label>
<input type="text" name="username" class="form-control" id="user" placeholder="请输入用户名"/>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" name="password" class="form-control" id="password" placeholder="请输入密码"/>
</div>
<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>
<hr/>
<div class="form-group" style="text-align: center;">
<input class="btn btn btn-primary" type="submit" value="登录">
</div>
</form>
<!-- 出错显示的信息框 -->
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert">
<span>×</span></button>
<strong>${requestScope.login_msg}</strong>
</div>
</div>
</body>
</html>
验证码Servlet
package com.mark.web.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* 验证码
*/
@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);
}
}
登录Servlet
package com.mark.web.servlet;
import com.mark.domain.User;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取数据
//获取用户填写的验证码
String verifycode = request.getParameter("verifycode");
//获取所有数据
Map<String, String[]> map = request.getParameterMap();
//3.校验验证码
HttpSession session = request.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
//确保验证码一致性
session.removeAttribute("CHECKCODE_SERVER");
if (!checkcode_server.equalsIgnoreCase(verifycode)) {
//验证码不正确
//提示信息
request.setAttribute("login_msg", "验证码错误!");
//跳转登录页面
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
//4.封装User对象
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//5.调用Service对象查询
UserService service = new UserServiceImpl();
User loginUser = service.login(user);
//6.判断是否登录成功
if (loginUser != null) {
//登录成功
//将用户存到session
session.setAttribute("user", loginUser);
//跳转页面
response.sendRedirect(request.getContextPath() + "/index.jsp");
} else {
//登录失败
//提示信息
request.setAttribute("login_msg", "用户名或密码错误!");
//跳转登录页面
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
7.2 添加功能
功能分析
功能实现
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- HTML5文档-->
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>添加用户</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<center><h3>添加联系人页面</h3></center>
<form action="${pageContext.request.contextPath}/addUserServlet" method="post">
<div class="form-group">
<label for="name">姓名:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
</div>
<div class="form-group">
<label>性别:</label>
<input type="radio" name="gender" value="男" checked="checked"/>男
<input type="radio" name="gender" value="女"/>女
</div>
<div class="form-group">
<label for="age">年龄:</label>
<input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄">
</div>
<div class="form-group">
<label for="address">籍贯:</label>
<select name="address" class="form-control" id="address">
<option value="广东">广东</option>
<option value="广西">广西</option>
<option value="湖南">湖南</option>
</select>
</div>
<div class="form-group">
<label for="qq">QQ:</label>
<input type="text" class="form-control" id="qq" name="qq" placeholder="请输入QQ号码"/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" class="form-control" id="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>
package com.mark.web.servlet;
import com.mark.domain.User;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.beans.JavaBean;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/addUserServlet")
public class AddUserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取所有数据
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.addUser(user);
//跳转到userListServlet
response.sendRedirect(request.getContextPath() + "/userListServlet");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在UserService中添加addUser方法
@Override
public void addUser(User user) {
dao.addUser(user);
}
在UserDao中添加addUser方法
@Override
public void addUser(User user) {
String sql= "insert into user values(null,?,?,?,?,?,?,null,null)";
template.update(sql,user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail());
}
7.3 删除功能
功能分析
功能实现
修改删除按钮链接
<script>
function deleteUser(id) {
//用户安全提示
if(confirm("您确定要删除吗?")){
//访问路径
location.href="${pageContext.request.contextPath}/deleteUserServlet?id="+id;
}
}
</script>
<c:forEach items="${requestScope.users}" var="user" varStatus="s">
<tr>
<th><input type="checkbox"></th>
<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="update.html">修改</a>
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a>
<%--这里的user.id中的user就是forEach循环中var的user--%>
</td>
</tr>
</c:forEach>
添加DeleteUserServlet
package com.mark.web.servlet;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/deleteUserServlet")
public class DeleteUserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取id
String id = request.getParameter("id");
//2.调用service删除
UserService userService = new UserServiceImpl();
userService.deleteUser(id);
//跳转到查询所有Servlet
response.sendRedirect(request.getContextPath() + "/userListServlet");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在UserService添加方法deleteUser
@Override
public void deleteUser(String id) {
dao.deleteUser(Integer.parseInt(id));
}
在UserDao中添加方法deleteUser
@Override
public void deleteUser(int id) {
String sql = "delete from user where id = ?";
template.update(sql,id);
}
7.4 修改功能
功能分析
功能实现
回显操作
修改list.jsp页面的修改按钮超链接
<a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>
添加FindUserServlet
package com.mark.web.servlet;
import com.mark.domain.User;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/findUserServlet")
public class FindUserServlet extends HttpServlet {
@Override
protected void doGet(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.将request转发到update.jsp
request.getRequestDispatcher("/update.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在UserService中添加findUserById方法
@Override
public User findUserById(String id) {
return dao.findUserById(Integer.parseInt(id));
}
在UserDao中添加findUserById方法
@Override
public User findUserById(int id) {
String sql = "select * from user where id = ?";
return template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
}
修改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>
<!-- 指定字符集 -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<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="" method="post">
<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="sex" value="男" checked />男
<input type="radio" name="sex" value="女"/>女
</c:if>
<c:if test="${user.gender == '女'}">
<input type="radio" name="sex" value="男" />男
<input type="radio" name="sex" 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" class="form-control" id="address">
<c:if test="${user.address == '广东'}">
<option value="广东" selected>广东</option>
<option value="北京">北京</option>
<option value="广西">广西</option>
<option value="湖南">湖南</option>
</c:if>
<c:if test="${user.address == '北京'}">
<option value="广东">广东</option>
<option value="北京" selected>北京</option>
<option value="广西">广西</option>
<option value="湖南">湖南</option>
</c:if>
<c:if test="${user.address == '广西'}">
<option value="广东">广东</option>
<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="广西">广西</option>
<option value="湖南" selected>湖南</option>
</c:if>
</select>
</div>
<div class="form-group">
<label for="qq">QQ:</label>
<input type="text" class="form-control" name="qq" id="qq" value="${user.qq}" placeholder="请输入QQ号码"/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" class="form-control" name="email" id="email" value="${user.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>
修改操作
设置提交表单路径,设置隐藏域
<form action="${pageContext.request.contextPath}/updateUserServlet" method="post">
<div class="form-group">
<!--隐藏域 提交id-->
<input type="hidden" name="id" value="${user.id}">
添加UpdateUserServlet
package com.mark.web.servlet;
import com.mark.domain.User;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Set;
@WebServlet("/updateUserServlet")
public class UpdateUserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取map
Map<String, String[]> map = request.getParameterMap();
/*Set<String> keyset =map.keySet();
for (String name : keyset) {
//根据key键获取值
String[] values = map.get(name);
System.out.println(name);
for (String value : values) {
System.out.println(value);
}
System.out.println("---------");
}
*/
//3.创建对象
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// System.out.println(user);
//html的name,要和封装属性值set的参数名称一致,如果不这样做,那么使用BeanUtils.populate()封装时,里面的键值就会为null
//4.调用UserService
UserService service = new UserServiceImpl();
service.updateUser(user);
//5.查询所有Servlet
response.sendRedirect(request.getContextPath() + "/userListServlet");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在UserService中添加updateUser方法
@Override
public void updateUser(User user) {
dao.updateUser(user);
}
在UserDao中添加updateUser方法
@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());
}
7.5 删除选中功能
功能分析
代码实现
选中id通过表单提交checkbox获取
<script>
window.onload = function () {
//给删除选中按钮添加单机事件
document.getElementById("delSelect").onclick = function () {
//完成表单提交
document.getElementById("delForm").submit();
}
}
</script>
<form id="delForm" action="${pageContext.request.contextPath}/delSelectedServlet" method="post">
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th><input type="checkbox"></th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<c:forEach items="${requestScope.users}" var="user" varStatus="s">
<tr>
<th><input type="checkbox" name="uid" value="${user.id}"></th>
<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>
<%--这里的user.id中的user就是forEach循环中var的user--%>
</td>
</tr>
</c:forEach>
</table>
</form>
编写delSelectedServlet
package com.mark.web.servlet;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/delSelectedServlet")
public class DelSelectedServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取所有id
String[] ids = request.getParameterValues("uid");
//调用Service
UserService service = new UserServiceImpl();
service.delSelectedUser(ids);
//跳转到查询所有Servlet
response.sendRedirect(request.getContextPath() + "/userListServlet");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在UserService下添加delSelectedUser方法
@Override
public void delSelectedUser(String[] ids) {
//遍历数字
for (String id : ids) {
//调用dao删除
dao.deleteUser(Integer.parseInt(id));
}
}
全选全不选功能实现
//全选全不选功能
//获取第一个checkbox
document.getElementById("firstCheckBox").onclick = function () {
//获取下边列表中所有的CheckBox
var cbs = document.getElementsByName("uid")
for (var i = 0; i < cbs.length; i++) {
//设置这些cbs[i]的checked状态 = firstCheckBox.checked
cbs[i].checked = this.checked;
}
}
在Sevice应该判断一下ids是否为空(或者在前端遍历cbs,有选中则提交),为空则不提交
@Override
public void delSelectedUser(String[] ids) {
if (ids != null && ids.length > 0) {
//遍历数字
for (String id : ids) {
//调用dao删除
dao.deleteUser(Integer.parseInt(id));
}
}
}
7.6 分页查询功能
好处:
减轻服务器内存的开销
提升用户体验
功能分析
代码实现
package com.mark.domain;
import java.util.List;
/**
* @ClassName PageBean
* @Description TODO 分页工具对象
* @Author Mark
* @Date 2022/8/16 10:37
* @Version 1.0
*/
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 +
'}';
}
}
package com.mark.web.servlet;
import com.mark.domain.PageBean;
import com.mark.domain.User;
import com.mark.service.UserService;
import com.mark.service.impl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/findUserByPageServlet")
public class FindUserByPageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取参数
String currentPage = request.getParameter("currentPage");//当前页码
String rows = request.getParameter("rows");//每页显示的条数
if (currentPage == null || "".equals(currentPage)){
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
System.out.println(pageBean);
request.setAttribute("pageBean",pageBean);
//4.转发到list.jsp
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
@Override
public PageBean<User> findUserByPage(String _currentPage, String _rows) {
int currentPage = Integer.parseInt(_currentPage);
int rows = Integer.parseInt(_rows);
if (currentPage <= 0){
currentPage = 1;
}
//1.创建空的PageBean对象
PageBean<User> pageBean = new PageBean<User>();
//2.设置参数
pageBean.setCurrentPage(currentPage);
pageBean.setRows(rows);
//3.调用dao查询总记录数
int totalCount = dao.findTotalCount();
pageBean.setTotalCount(totalCount);
//4.调用dao查询list集合
//计算开始的记录索引
int start = (currentPage - 1) * rows;
List<User> list = dao.findByPage(start, rows);
pageBean.setList(list);
//5.计算总页码
int totalPage = totalCount % rows == 0 ? totalCount / rows : (totalCount / rows) + 1;
pageBean.setTotalPage(totalPage);
return pageBean;
}
@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 ? , ?";
return template.query(sql,new BeanPropertyRowMapper<User>(User.class),start,rows);
}
<%@ 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>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>用户信息管理系统</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<style type="text/css">
td, th {
text-align: center;
}
</style>
<script>
function deleteUser(id) {
//用户安全提示
if (confirm("您确定要删除吗?")) {
//访问路径
location.href = "${pageContext.request.contextPath}/deleteUserServlet?id=" + id;
}
}
window.onload = function () {
//给删除选中按钮添加单机事件
document.getElementById("delSelect").onclick = function () {
if (confirm("您确定要删除选中条目吗?")) {
//完成表单提交
document.getElementById("delForm").submit();
}
}
//全选全不选功能
//获取第一个checkbox
document.getElementById("firstCheckBox").onclick = function () {
//获取下边列表中所有的CheckBox
var cbs = document.getElementsByName("uid")
for (var i = 0; i < cbs.length; i++) {
//设置这些cbs[i]的checked状态 = firstCheckBox.checked
cbs[i].checked = this.checked;
}
}
}
</script>
</head>
<body>
<div class="container">
<h3 style="text-align: center">用户信息列表</h3>
<div style="float: left;margin: 5px">
<form class="form-inline">
<div class="form-group">
<label for="exampleInputName2">姓名</label>
<input type="text" class="form-control" id="exampleInputName2" placeholder="">
</div>
<div class="form-group">
<label for="exampleInputName3">籍贯</label>
<input type="text" class="form-control" id="exampleInputName3" placeholder="">
</div>
<div class="form-group">
<label for="exampleInputEmail2">邮箱</label>
<input type="email" class="form-control" id="exampleInputEmail2" placeholder="">
</div>
<button type="submit" class="btn btn-default">查询</button>
</form>
</div>
<div style="float: right;margin: 5px">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
<a class="btn btn-primary" href="javascript:void(0);" id="delSelect">删除选中</a>
</div>
<form id="delForm" action="${pageContext.request.contextPath}/delSelectedServlet" method="post">
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th><input type="checkbox" id="firstCheckBox"></th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<c:forEach items="${requestScope.pageBean.list}" var="user" varStatus="s">
<tr>
<th><input type="checkbox" name="uid" value="${user.id}"></th>
<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>
<%--这里的user.id中的user就是forEach循环中var的user--%>
</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 class="disabled">
</c:if>
<c:if test="${pageBean.currentPage != pageBean.totalPage}">
<li>
</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: 10px">
共${pageBean.totalCount}条记录,共${pageBean.totalPage}页
</span>
</ul>
</nav>
</div>
</div>
</body>
</html>
7.7 复杂条件查询功能
功能分析
代码实现
<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" >
</div>
<div class="form-group">
<label for="exampleInputName3">籍贯</label>
<input type="text" name="address" value="${condition.address[0]}" class="form-control" id="exampleInputName3" >
</div>
<div class="form-group">
<label for="exampleInputEmail2">邮箱</label>
<input type="text" name="email" value="${condition.email[0]}" class="form-control" id="exampleInputEmail2" >
</div>
<button type="submit" class="btn btn-default">查询</button>
</form>
</div>
Map<String, String[]> condition = request.getParameterMap();
//2.调用service查询
UserService service = new UserServiceImpl();
PageBean<User> pageBean = service.findUserByPage(currentPage, rows,condition);
//3.将pageBean存入request
System.out.println(pageBean);
request.setAttribute("pageBean",pageBean);
request.setAttribute("condition",condition);
//4.转发到list.jsp
request.getRequestDispatcher("/list.jsp").forward(request,response);
//3.调用dao查询总记录数
int totalCount = dao.findTotalCount(condition);
pageBean.setTotalCount(totalCount);
//4.调用dao查询list集合
//计算开始的记录索引
int start = (currentPage - 1) * rows;
List<User> list = dao.findByPage(start, rows,condition);
//定义模板初始化sql
String sql="select count(*) from user where 1 = 1";
StringBuilder sb=new StringBuilder(sql);
//遍历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+"%");//?条件的值
}
}
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);
//遍历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 + "%");//?条件的值
}
}
//添加分页查询
sb.append(" limit ? , ? ");
//添加分页查询参数值
params.add(start);
params.add(rows);
sql = sb.toString();
System.out.println(sql);
System.out.println(params);
return template.query(sql, new BeanPropertyRowMapper<User>(User.class), params.toArray());
}