在index.jsp首页中添加一个a标签,跳转到登录页面
创建一个login.jsp作为登录页面,书写form表单指定提交地址和提交方式
创建实体类----User
package com.wen.bean;
public class User {
private Integer uid;
private String username;
private String password;
private String phone;
private String address;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
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;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
", password='" + password + '\'' +
", phone='" + phone + '\'' +
", address='" + address + '\'' +
'}';
}
}
创建实体类----Goods
package com.wen.bean;
public class Goods {
private Integer gid;
private String gname;
private String price;
private String mark;
public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getMark() {
return mark;
}
public void setMark(String mark) {
this.mark = mark;
}
@Override
public String toString() {
return "Goods{" +
"gid=" + gid +
", gname='" + gname + '\'' +
", price='" + price + '\'' +
", mark='" + mark + '\'' +
'}';
}
}
1、设置请求和响应的编码
2、获取请求参数
3、业务处理---JDBC操作
步骤:
加载数据库驱动
获取数据库连接
定义登录的sql语句
获取预处理对象
传参
执行查询
解析结果集------从结果集中获取数据,然后封装到实体类对象中
关闭资源
try {
//1.加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接
con= DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC","root","root");
//3.定义登录的sql语句
String sql="select * from t_user where username=? and password=?";
//4.获取预处理对象
pstm=con.prepareStatement(sql);
//5.传参
pstm.setObject(1,username);
pstm.setObject(2,password);
//6.执行查询
rs=pstm.executeQuery();
//7.解析结果集
if (rs.next()){
Login= new User();
//从结果集中获取数据,然后封装到实体类对象中
int uid=rs.getInt("uid");
Login.setUid(uid);
Login.setUsername(rs.getString("username"));
Login.setPassword(rs.getString("password"));
Login.setPhone(rs.getString("phone"));
Login.setAddress(rs.getString("address"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
//8.关闭资源
try {
if(rs!=null){
rs.close();
}
if(pstm!=null){
pstm.close();
}
if(con!=null){
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
创建一个zhuye.jsp作为跳转页面
在error.jsp中添加一个a标签,出错后跳转到登录页面
4、判断登录的用户信息是否为空
创建工具类----jdbc
package com.wen.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCUtil {
private static String driver="com.mysql.cj.jdbc.Driver";
private static String url="jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC";
private static String user="root";
private static String password="root";
private static Connection con=null;
/**
* 获取数据库连接对象
* @return
*/
public static Connection getCon() {
try {
//1.加载数据库驱动
Class.forName(driver);
//2.获取数据库连接
con=DriverManager.getConnection(url,user,password);
}catch (Exception e){
e.printStackTrace();
}
return con;
}
/**
* 查询的资源关闭
* @param rs
* @param pstm
* @param con
*/
public static void close(ResultSet rs, PreparedStatement pstm,Connection con){
try{
if(rs!=null){
rs.close();
}
if(pstm!=null){
pstm.close();
}
if(con!=null){
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 更新的资源关闭
* @param pstm
* @param con
*/
public static void close( PreparedStatement pstm,Connection con){
try{
if(pstm!=null){
pstm.close();
}
if(con!=null){
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建接口
package com.wen.dao;
import com.wen.bean.User;
public interface UserDao {
/**
* 完成用户的登录操作
* @param username
* @param password
* @return
*/
User login(String username,String password);
/**
* 完成用户信息注册
* @param user 封装了用户信息
* @return 插入数据库后受影响的行数
*/
int register(User user);
}
完善接口
package com.wen.dao.impl;
import com.wen.bean.User;
import com.wen.dao.UserDao;
import com.wen.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserDaoImpl implements UserDao {
private Connection con=null;//数据库连接对象
private PreparedStatement pstm=null;//预处理对象
private ResultSet rs=null;//结果集对象
private int row=0;//增删改受影响的行数
User login=null;
public User login(String username,String password){
try {
con= JDBCUtil.getCon();
//3.定义登录的sql语句
String sql="select * from t_user where username=? and password=?";
//4.获取预处理对象
pstm=con.prepareStatement(sql);
//5.传参
pstm.setObject(1,username);
pstm.setObject(2,password);
//6.执行查询
rs=pstm.executeQuery();
//7.解析结果集
if (rs.next()){
login= new User();
//从结果集中获取数据,然后封装到实体类对象中
int uid=rs.getInt("uid");
login.setUid(uid);
login.setUsername(rs.getString("username"));
login.setPassword(rs.getString("password"));
login.setPhone(rs.getString("phone"));
login.setAddress(rs.getString("address"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
//8.关闭资源
JDBCUtil.close(rs,pstm,con);
}
return login;
}
public int register(User user) {
try {
con= JDBCUtil.getCon();
//定义sql语句
String sql="insert into t_user(username,password,phone,address)values(?,?,?,?)";
//获取预处理对象
pstm = con.prepareStatement(sql);
//传参
pstm.setObject(1,user.getUsername());
pstm.setObject(2,user.getPassword());
pstm.setObject(3,user.getPhone());
pstm.setObject(4,user.getAddress());
//执行sql
row=pstm.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(pstm,con);
}
return row;
}
}
注册页面
实现注册代码
package com.wen.servlet;
import com.wen.bean.User;
import com.wen.dao.UserDao;
import com.wen.dao.impl.UserDaoImpl;
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.io.IOException;
@WebServlet("/register")
public class Register extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.设置请求和响应的编码
req.setCharacterEncoding("utf-8");//设置请求的编码
resp.setCharacterEncoding("utf-8");//设置响应的编码
//2.获取请求参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String phone = req.getParameter("phone");
String address = req.getParameter("address");
//封装到User对象中
User user=new User();
user.setUsername(username);
user.setPassword(password);
user.setPhone(phone);
user.setAddress(address);
System.out.println(user);
//JDBC操作
UserDao userDao=new UserDaoImpl();
int row=userDao.register(user);
//做出响应
if (row>0){
resp.sendRedirect("login.jsp");
}else{
resp.sendRedirect("register.jsp");
}
}
}
注册成功跳转到登录页面
会话管理和使用
1、HTTP协议概述
HTTP是超文本传输协议的英文缩写,是基于TCP/IP通讯协议之上用来传输HTML和图片文件的应用协议,原本是用来从万维网服务器传输超文本到本地浏览器。它是一个应用层面向对象的协议,优点是简捷、快速,适用于分布式超媒体信息系统。于1990年提出,经过多年的完善和扩展已经非常地成熟。HTTP协议主要工作于B—S架构之上,这个时候浏览器作为HTTP的客户端通过URL向HTTP的服务器(web1、HTTP协议概述服务器)发送所有请求,web服务器根据接收到的请求后,向客户端发送响应信息。客户端向服务器请求发送时,需要传送请求方法和路径。路径就是URL,而HTTP常用的请求方法为GET和POST方法,每种方法规定了客户端与服务器通讯方式和数据报文。
HTTP协议报文
客户端与服务器的通讯都是通过一个个请求来实现的,一个HTTP请求的消息包括:请求行、请求头部、空行、请求数据四个部分组成。
服务器收到请求后,需要响应,而响应的消息也由四个部分组成:状态行、消息报头、空行、响应正文。
什么是无状态
2、会话概述
什么是会话?
当前浏览器与服务器间多次的请求、响应关系,被称作一个会话
第一次请求表示会话的开始
关闭浏览器或超时则表示会话的结束
HttpSession对象
服务器为每个会话创建一个HttpSession对象
每个会话对象都有一个唯一的ID
把用户的数据保存在相应的HttpSession对象内
使用HttpServletRequest的getSession()方法创建会话
public HttpSession getSession();
public HttpSession getSession(boolean value);
会话的使用
会话创建好以后,可以使用HttpSession接口进行会话的基本使用
会话保存数据
获取会话保存的数据
HttpSession接口提供了管理会话的方法
方法 | 说明 |
String getld() | 返回Session的ID |
long getCreationTime() | 返回会话被创建的时间 |
long getLastAccessedTime() | 返回会话最后处理时间 |
void invalidate() | 使当前的Session失效,此时Servlet容器会释放HttpSession对象占用的资源 |
void setAttribute(String name,Object value) | 将一个名/值对保存在HttpSession对象中 |
Object getAttribute(String name) | 根据name参数返回保存在HttpSession 对象中的属性值 |
3、会话跟踪技术
会话跟踪技术允许服务器确定访问站点的用户、用户访问站点的次数和用户停留站点的时间段客户端和服务器之间的会话ID和状态信息,通常有四种方法:
- 使用Cookie(存储在客户端浏览器)
- 使用ServletAPI中的Session会话机制(存储在Web服务器)
- URL重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对
- 隐藏表单域:<input type="hidden">,非常适合步需要大量数据存储的会话应用
3.1、Cookie机制
- cookie机制采用的是在客户端保持HTTP状态信息的方案。
Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带 传送给浏览器的一个小文本文件。
- 一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都会在HTTP请求头中将这个Cookie回传给WEB服务器。
- 底层的实现原理:WEB服务器通过在HTTP响应消息中增加Set—Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
- 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)
- 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
Cookie的传送过程示意图
Cookie的工作原理:在某个浏览器中保存数据后,服务端会将数据写到客户端的本地中,以cookie的保存机制保存。由于http协议的无状态,服务器忘记了之前的所有请求,它无法确定这一次请求的客户端,就是之前登录成功的那个客户端。
简单理解:就是将服务器端的东西写到客户端中,比如,使用账号登录某个网页时,大多浏览器会弹出一个提示框(访问是否保存账号与密码),选择保存后,保存的账号以及密码会使用cookie机制保存到客户端,下次再登录这个网站就不再需要输入账号与密码了。
请求转发------请求查询所有的商品信息
package com.wen.servlet;
import com.wen.bean.Goods;
import com.wen.bean.User;
import com.wen.dao.GoodsDao;
import com.wen.dao.UserDao;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class Login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.设置请求和响应的编码
req.setCharacterEncoding("utf-8");//设置请求的编码
resp.setCharacterEncoding("utf-8");//设置响应的编码
resp.setContentType("text/html;charset=UTF-8");//设置响应的文本格式和编码
//2.获取请求参数
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
//3.业务处理---JDBC操作
UserDao userDao=new UserDao();
User login = userDao.login(username, password);
//判断登录的用户信息是否为空
if (login!=null){
System.out.println("登录成功");
//登录成功后,在session中保存用户的个人信息
HttpSession session = req.getSession();
session.setAttribute("user",login);
//请求业务换了-----换成请求查询所有的商品信息
//请求转发
req.getRequestDispatcher("selectAllGoods").forward(req,resp);
}else{
//登录失败,跳转到错误页
resp.sendRedirect("error.jsp");
}
}
}
把商品信息传输到页面中进行展示----此处借助HttpSession传输数据
package com.wen.servlet;
import com.wen.bean.Goods;
import com.wen.dao.GoodsDao;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
@WebServlet("/selectAllGoods")
public class SelectAllGoods extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.设置请求和响应的编码
req.setCharacterEncoding("utf-8");//设置请求的编码
resp.setCharacterEncoding("utf-8");//设置响应的编码
System.out.println("SelectAllGoods......doPost");
//去查询 数据库中商品信息表中的数据
GoodsDao goodsDao=new GoodsDao();
List<Goods> goodsList=goodsDao.selectAll();
System.out.println(goodsList);
//如何把商品信息传输到页面中进行展示----此处借助HttpSession传输数据
HttpSession session = req.getSession();//获取HttpSession对象
//把查询到商品信息集合存储到session对象中,起名字叫做goodsList
session.setAttribute("goodsList",goodsList);
resp.sendRedirect("zhuye.jsp");
}
}
在主页中展示出来
EL表达式是通过 ${} 从作用域对象中自动获取数据,如果是对象可以通过 . 访问其属性
<%@ page import="com.wen.bean.Goods" %>
<%@ page import="java.util.List" %><%--
Created by IntelliJ IDEA.
User: hcyns
Date: 2023/2/17
Time: 19:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--在页面导入jstl的核心类库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<%--EL表达式是通过 ${} 从作用域对象中自动获取数据,如果是对象可以通过 . 访问其属性--%>
<h2>欢迎${user.address}的${user.username}来到主页!</h2>
<table>
<tr>
<th>商品编号</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品说明</th>
</tr>
<%--items:要遍历的集合元素 var:临时变量--%>
<c:forEach items="${goodsList}" var="goods">
<tr>
<td>${goods.gid}</td>
<td>${goods.gname}</td>
<td>${goods.price}</td>
<td>${goods.mark}</td>
</tr>
</c:forEach>
</table>
</body>
</html>