MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范,是将业务逻辑、数据、显示分离的方法来组织代码。
创建数据库
一、创建登录页
<html>
<head>
<title>登录页</title>
</head>
<body>
<h2>登录</h2>
<%-- action是表单要提交得地址 method表单要提交的方式 --%>
<form action="login" method="post">
账号:<input type="text" name="username" value=""/> <br/>
密码:<input type="password" name="password" value=""/> <br/>
<input type="submit" value="登录"/>
<a href="register.jsp">没有账号?点击注册</a>
</form>
</body>
</html>
二、 点击注册跳转到注册页
<html>
<head>
<title>注册页</title>
</head>
<body>
<h2>进行注册</h2>
<form action="register" method="post">
账号:<input type="text" name="username" value=""/> <br/>
密码:<input type="password" name="password" value=""/> <br/>
电话:<input type="text" name="phone" value=""/> <br/>
地址:<input type="text" name="address" value=""/> <br/>
<input type="submit" value="登录">
<a href="login.jsp">已有账号?去登录</a>
</form>
</body>
</html>
进行分层
三、设置响应和请求的编码,获取请求参数
注册:
全查
四、业务处理---JDBC操作
1.创建工具类 (util),抽取公共代码
package com.chen.util;
import java.sql.*;
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 {
Class.forName(driver);
con= DriverManager.getConnection(url,user,password);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return 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();
}
}
public static void close(PreparedStatement pstm,Connection con){
try {
if (pstm != null) {
pstm.close();
}
if (con != null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.连接数据库
2.编写sql
3.传参
4.执行sql语句
因为已经抽取公共类到util包,所以可以直接调用
注册:
package com.chen.dao;
import com.chen.bean.User;
import com.chen.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserDao {
private Connection connection=null;
private PreparedStatement pstm=null;
private ResultSet rs=null;
private int row=0;
private User login=null;
public User login(String username,String password){
try{
connection= JDBCUtil.getCon();
//定义登录的sql语句
String sql="select * from t_user where username=? and password=?";
//获取预处理对象
pstm=connection.prepareStatement(sql);
//传参
pstm.setObject(1,username);
pstm.setObject(2,password);
//执行查询
rs=pstm.executeQuery();
//解析结果集
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 {
JDBCUtil.close(rs,pstm,connection);
}
return login;
}
public int register(User user){
try {
connection= JDBCUtil.getCon();
//定义登录的sql语句
String sql="insert into t_user(username,password,phone,address)values(?,?,?,?)";
//获取预处理对象
pstm=connection.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,connection);
}
return row;
}
}
全查:
package com.chen.dao;
import com.chen.bean.Goods;
import com.chen.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class GoodsDao {
private Connection connection=null;//数据库连接
private PreparedStatement pstm=null;//预处理对象
private ResultSet rs=null;//结果集处理
private int row=0;//增删改受影响的行数
public List<Goods> selectAll(){
List<Goods> goodsList=new ArrayList<>();
try {
connection=JDBCUtil.getCon();
String sql="select * from t_goods";
pstm=connection.prepareStatement(sql);
rs=pstm.executeQuery();
while (rs.next()){
//把当前数据行中的数据取出来,储存到Googs对象中
Goods goods=new Goods();
goods.setGid(rs.getInt("gid"));
goods.setGname(rs.getString("gname"));
goods.setPrice(rs.getString("price"));
goods.setMark(rs.getString("mark"));
//把Goods对象储存到集合中
goodsList.add(goods);
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,pstm,connection);
}
return goodsList;
}
}
判断登录是否成功:
UserDao userDao=new UserDao();
User login=userDao.login(username,password);
//判断登录的用户信息是否为空
if (login != null) {
//去查询 数据库表中商品信息表中的数
// GoodsDao goodsDao=new GoodsDao();
// List<Goods> goodsList=goodsDao.selectAll();
// System.out.println(goodsList);
System.out.println("登录成功!");
//1.登录成功后,在session中保存用户的个人信息
HttpSession session=req.getSession();
session.setAttribute("user",login);
//请求转发--登录业务已经处理完毕,请做请求转发,让别的servlet执行商品信息的查询
req.getRequestDispatcher("selectAllGoods").forward(req,resp);
//登录成功,跳转到主页面
//resp.sendRedirect("zhuye.jsp");//指定跳转的页面
} else {
//登录失败
resp.sendRedirect("error.jsp");
}
成功之后请求转发,让别的servlet执行商品信息的查询
req.getRequestDispatcher("selectAllGoods").forward(req,resp);
把查询到的信息传输到页面上展示---此时借助HttpSession传输数据
HttpSession session=req.getSession();
最后跳转到指定的页面(主页)
查询页面展示:
<%@ page import="java.util.List" %>
<%@ page import="com.chen.bean.Goods" %>
<%@ page import="com.chen.bean.User" %><%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2023/2/17
Time: 19:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>主页</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>
注册之后查询数据库看是否有数据
查询:
用到了EL标签:表达式
${ }
通过${}从作用域对象中自动获取数据,如果是对象可以通过.(点)访问其属性
例如:username是张三,useraddress是南阳
${user.address}的{user.username}
输出:南阳的张三
JSTL标签:
在页面导入JSTL的核心类库写
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
HTTP特点:
无状态:就是Http协议不记录用户信息,假如服务器收到了两次访问记录,但是服务器无法确定是一个用户访问了两次还是两个用户分别访问了一次。因此为了区分用户,需要为不同用户作等级
HttpSession对象
服务器为每个会话创建一个HttpSession对象,每个会话对象都有一个唯一的id把用户的数据保存在相映的HttpSession对象内。
2、会话概述
什么是会话?
当前浏览器与服务器间多次的请求、响应关系,被称作一个会话
第一次请求表示会话的开始
关闭浏览器或超时则表示会话的结束。默认的有效期30分钟
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 对象中的属性值 |
会话跟踪技术允许服务器确定访问站点的用户、用户访问站点的次数和用户停留站点的时间段客户端和服务器之间的会话ID和状态信息,通常有四种方法:
1.使用Cookie(存储在客户端浏览器)
2.使用ServletAPI中的Session会话机制(存储在Web服务器)
3.URL重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对
4.隐藏表单域:<input type="hidden">,非常适合步需要大量数据存储的会话应用
Cookie机制
1.cookie机制采用的是在客户端保持HTTP状态信息的方案。
Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一个小文本文件。
2.一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都会在HTTP请求头中将这个Cookie回传给WEB服务器。
3.底层的实现原理:WEB服务器通过在HTTP响应消息中增加Set—Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
4.一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)
5.一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
6.浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
Cookie的传送过程示意图Cookie的工作原理:
在某个浏览器中保存数据后,服务端会将数据写到客户端的本地中,以cookie的保存机制保存。由于http协议的无状态,服务器忘记了之前的所有请求,它无法确定这一次请求的客户端,就是之前登录成功的那个客户端。
简单理解:就是将服务器端的东西写到客户端中,比如,使用账号登录某个网页时,大多浏览器会弹出一个提示框(访问是否保存账号与密码),选择保存后,保存的账号以及密码会使用cookie机制保存到客户端,下次再登录这个网站就不再需要输入账号与密码了。