会话:一次会话中包含多次请求和响应
功能:在一次会话的范围内的多次请求间共享数据
方式:
概念:客户端会话技术,将数据保存在客户端
使用步骤:
创建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;
/**
@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
*/
}
}
基于响应头set-cookie和请求体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)
@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不能直接存储中文数据
在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可以共享
setDomain(".baidu.com")
,那么tieba.baidu.com和news.baidu.com中cookie可以共享特点
作用:
需求:
分析:
可以采用Cookie完成
在服务器的Servlet中判断是否有一个名为lastTime的cooike
有:不是第一次访问
没有:是第一次访问
@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("您好,欢迎您首次访问");
}
}
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
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);
}
}
Session的实现依赖于Cookie,通过请求头和响应头实现
当客户端关闭后,服务器不关闭,两次获取Session是否为同一个?
默认情况下不是
//期望关闭客户端后,session也能相同:保存到客户端
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60*60);
客户端不关闭,服务器关闭,两次获取的Session是否为同一个?
不是同一个,但是要确保数据不丢失
Session的钝化
Session的活化
服务器会自动完成Session的钝化和活化,但是IDEA不会
Session什么时候被销毁?
void invalidate()
Session用于存储一次会话的多次请求的数据,存在服务器端
Session可以存储任意类型、任意大小的数据
Session与Cookie的区别
需求:
分析:
实现:
创建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);
}
}
概念:Java Server Pages:java服务器页面
可理解为一个特殊的页面,其中既可以直接定义HTML的标签,又可以编写Java代码
用于简化书写
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <h1>hi~jsp</h1>
JSP的脚本:JSP定义Java代码的方式
<& 代码 &>
:定义的Java代码在service方法中。service中可以定义什么,该脚本就可以定义什么
<%
System.out.println("hello jsp");
int i = 5;//局部变量
%>
<&! 代码 &>
:定义的Java代码在jsp转换后的java类的成员位置。
<%!
int i = 3;//成员变量
%>
<&= 代码 &>
:定义的Java代码会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
<%= i + "hello" // 5hello 会打印局部变量%>
在jsp页面中不需要获取和创建,直接可以使用的对象称为JSP的内置对象
一共有9个内置对象
request
response
out:字符输出流对象。可以将数据输出到页面上。和response.getWrite()类似
response.getWrite()和out.write()区别:前者永远会先于后者输出
在tomcat服务器真正给客户端浏览器做出响应前,会先找response缓冲区数据,再找out缓冲区数据
//响应数据
String value = c.getValue();
value = URLDecoder.decode(value, "utf-8");
%>
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);
%>
作用:用于配置JSP页面,导入资源文件
格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2%>
分类:
page:配置JSP页面
contentType:等同于response.setContentType()
pageEcoding:设置当前JSP页面的编码
import:导包
errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
<%@ page errorPage="error.jsp" %>
isErrorPage:表示当前页面是否为错误页面。true/false
include:在当前页面中导入项目中其他的页面
<%@ include file="top.jsp" %>
taglib:导入资源。一般用于导入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix:前缀(自定义)
html注释:
<!-- -->
:只能注释html代码片段
JSP注释:推荐使用
<%-- --%>
:可注释所有
在JSP页面中不需要创建,直接使用的对象
变量名
真实类型
作用
pageContext
PageContext
当前页面共享数据,还可以获取其他八个内置对象
request
HttpServletRequest
一次请求访问的对个资源(转发)
session
HttpSession
一次会话的多个请求间
application
ServletContext
所有用户间共享数据
response
HttpServletResponse
响应对象
page
Object
当前页面(Servlet)的对象,可理解为this
out
JspWriter
输出对象,数据输出到页面上
config
ServletConfig
Servlet的配置对象
exception
Throwable
异常对象
前四个:域对象。用于共享数据
MVC:将一个程序分为M、V、C三个部分。
M:Model,模型。JavaBean
V:View,视图。JSP
C:Controller,控制器。Servlet
优点:
缺点:
概念:Expression Language 表达式语言
作用:替换和简化jsp页面中java代码的编写
语法:${表达式}
eg:${3 > 4}
输出false
注意:
isELIgnored
为true时将不会解析此页面的EL表达式\${3 > 4}
运算
运算符:
算术运算符:+ - * /(div) %(mod)
比较运算符: > < >= <= == !=
逻辑运算符:&&(and) ||(or) !(not)
空运算符:empty
${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" %>
${3 + 4}
${3 / 4}
${3 div 4}
${3 % 4}
${3 mod 4}
${3 == 4}
${3 != 4}
${3 > 4 && 3 < 4}
${3 > 4 and 3 < 4}
${3 > 4 && 3 < 4}
${3 > 4 and 3 < 4}
获取值
EL表达式只能从域对象中获取值
语法:
${域名称.键名}
:从指定域中获取指定键的值
域名称:
pageScope
--->pageContextrequestScope
--->requestsessionScope
--->sessionapplicationScope
--->application(ServletContext)${键名}
:表示依次从最小的域中查找是否又该键对应的值,直到找到为止。
${requestScope.name}
${sessionScope.age}
${sessionScope.haha}<%--当为null时返回空字符串,不会影响页面布局--%>
${name}<%--zhangsan--%>
${sessionScope.name}<%--lisi--%>
获取对象、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" %>request.setAttribute("u", user);
%>
${requestScope.u}
<%--
通过对象的属性获取
setter或getter方法,去掉set或get,再将剩余部分首字母变为小写,得到的内容称之为属性
setName ---> Name --->name
--%>
${requestScope.u.name}
${requestScope.u.age}
${requestScope.u.birthday}
${requestScope.u.birthday.month}<%--7--%>
${requestScope.u.birStr}
<%-- 2022-08-07 23:14:37--%>
/**
* 逻辑视图
* @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
${empty str}
<%--false--%>
<%--true--%>
${not empty str}
<%--false--%>
隐式对象:
${pageContext.request.contextPath}
概念:JavaServer Page Tag Library JSP标准标签库
是由Apache组织提供的开源的JSP标签
作用:用于简化和替换jsp页面的java代码
使用步骤:
<%@ taglib%>
if:相当于Java的if语句
属性
test是必须属性 接收boolean表达式
c:if
标签choose:相当于Java的switch语句
完成数字编号对应星期几案例
<% request.setAttribute("number",3); %>foreach:相当于Java的for循环语句
完成重复的操作
for(int i = 0;i < 10;i++){
...
}
属性:
遍历容器
List<User> list = new ArrayList<>();
for(User user : list){
...
}
属性:
<%--
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);
%>
需求:
编号 | 姓名 | 年龄 | 生日 |
---|---|---|---|
${s.count} | ${user.name} | ${user.age} | ${user.birStr} |
三层架构:软件设计架构
需求:用户信息的增删改查操作
设计:
技术选型: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)
);
开发:
环境搭建
编码
实现:
编写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();
}</code></pre></li>
在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>
测试
部署运维
基于6.1案例完成
简单功能:
复杂功能
调整页面,加入验证码功能
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 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>
验证码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());
}
/**
登录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
//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);
}
}
功能分析
功能实现
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 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>
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
//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());
}
修改删除按钮链接
<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);
}
功能实现
回显操作
修改list.jsp页面的修改按钮超链接
添加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>
修改操作
设置提交表单路径,设置隐藏域