JavaWeb 笔记——4
- 一、JSP
 - 1.1、JSP概述
 - 1.2、JSP快速入门
 - 1.3、JSP原理
 - 1.4、JSP脚本
 - 1.5、JSP缺点
 - 1.6、EL表达式
 - 1.7、JSTL标签
 - 1.8、MVC模式和三层架构
 
- 二、介于三层框架下的案例
 - 2.1、准备环境
 - 2.2、查询所有
 - 2.3、添加
 - 2.4、修改
 - 2.4.1、修改-回显数据
 - 2.4.2、修改-修改数据
 
- 2.5、删除
 
- 三、会话跟踪技术
 - 3.1、会话跟踪技术概述
 - 3.2、Cookie 基本使用
 - 3.3、Cookie原理
 - 3.4、Cookie细节
 - 3.5、Session 基本使用
 - 3.6、Session 原理
 - 3.7、Session 使用细节
 - 3.8、小结
 
- 四、会话跟踪-登录注册案例
 - 4.1、需求说明
 - 4.2、用户登录
 - 4.3、记住用户
 - 4.4、注册用户
 - 4.5、验证码-展示&校验
 
一、JSP
1.1、JSP概述
- 概念: Java Server Pages,Java服务端页面
 - 一种动态的网页技术,其中既可以定义HTML、JS、CSS等静态内容,还可以定义Java代码的动态内容
 - JSP = HTML + Java
 - JSP作用:简化开发,避免了在Servlet中直接输出HTML标签
 
1.2、JSP快速入门
-  
导入JSP坐标
<dependency> <groupId>javax.servlet.jsp</groupld> <artifactld>jsp-api</artifactld> <version>2.2</version> <scope>provided</scope> </dependency> -  
创建JSP文件
 -  
编写HTML标签和Java代码
<body> <h1>hello jsp~</h1> <% System.out.printf("jsp hello~");%> </body> 
1.3、JSP原理
- JSP本质上就是一个Servlet
 - JSP在被访问时,由JSP容器(Tomcat)将其转换为Java文件(Servlet),在由JSP容器(Tomcat)将其编译,最终对外提供服务的其实就是这个字节码文件
 

1.4、JSP脚本
- JSP脚本用于在JSP页面内定义Java代码.
 - JSP脚本分类: 
  
<%...%>:内容会直接放到_jspService()方法之中<%=...%>:内容会放到out.print()中,作为out.print()的参数<%!..%>:内容会放到_jspService()方法之外,被类直接包含
 

<%@ page import="com.Smulll.pojo.Brand" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %><%--
  Created by IntelliJ IDEA.
  User: 20265
  Date: 2023/7/5
  Time: 16:50
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    //查询数据库
    List<Brand> brands = new ArrayList<Brand>();
    brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
<%
    for (int i = 0; i < brands.size(); i++) {
        Brand brand = brands.get(i);
%>
    <tr align="center">
        <td><%=brand.getId()%></td>
        <td><%=brand.getBrandName()%></td>
        <td><%=brand.getCompanyName()%></td>
        <td><%=brand.getOrdered()%></td>
        <td><%=brand.getDescription()%></td>
        <%
            if (brand.getStatus() == 1){
        %>
             <td><%="启用"%></td>
        <%
            }else {
        %>
            <td><%="禁用"%></td>
        <%
            }
        %>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
<%
    }
%>
</table>
</body>
</html>
 
1.5、JSP缺点
- 由于JSP页面内,既可以定义HTML标签,又可以定义Java代码,造成了以下问题: 
  
- 书写麻烦:特别是复杂的页面
 - 阅读麻烦
 - 复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…
 - 占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
 - 调试困难:出错后,需要找到自动生成的.java文件进行调试
 - 不利于团队协作:前端人员不会Java,后端人员不精HTML
 - …
 
 
JSP已逐渐退出历史舞台
1.6、EL表达式
-  
Expression Language表达式语言,用于简化JSP页面内的Java代码
 -  
主要功能:获取数据
 -  
语法:
${expression}
${brands}:获取域中存储的key为brands的数据 -  
JavaWeb中的四大域对象:
- page:当前页面有效
 - request:当前请求有效
 - session:当前会话有效
 - application:当前应用有效
 
 
el表达式获取数据,会依次从这4个域中寻找,直到找到为止
 
1.7、JSTL标签
- JSP标准标签库(Jsp Standarded Tag Library),使用标签取代JSP页面上的Java代码
 - 例:
<c:if test="${flag ==1}"> 男 </c:if> <c:if test="${flag == 2}"> 女 </c:if> 
JSTL快速入门
- 导入坐标
<dependency> <groupId>jstl</groupId> <artifactId>jstl<lartifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> - 在JSP页面上引入JSTL标签库
 
<%@ taglib prefix= "c" uri= "http://java.sun.com/jsp/jstl/core" %>
 
- 使用 
  
<C:if>
 
<%--
  Created by IntelliJ IDEA.
  User: 20265
  Date: 2023/7/5
  Time: 20:20
  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</title>
</head>
<body>
    <c:if test="true" >
      <h1>你好!!!</h1>
    </c:if>
</body>
</html>
 
<c:forEach>:相当于for循环- items:被遍历的容器
 - var:遍历产生的临时变量
 - varStatus:遍历状态对象 
    
- count:从1开始遍历的数字
 - status:从0开始遍历的数字

 
 - begin:开始数
 - end:结束数
 - step:步长

 
<%@ page import="com.Smulll.pojo.Brand" %><%--
  Created by IntelliJ IDEA.
  User: 20265
  Date: 2023/7/5
  Time: 20:28
  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</title>
</head>
<body>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
  <tr>
    <th>序号</th>
    <th>品牌名称</th>
    <th>企业名称</th>
    <th>排序</th>
    <th>品牌介绍</th>
    <th>状态</th>
    <th>操作</th>
  </tr>
  <c:forEach items="${brands}" var="brand">
    <tr align="center">
      <td>${brand.id}</td>
      <td>${brand.brandName}</td>
      <td>${brand.companyName}</td>
      <td>${brand.ordered}</td>
      <td>${brand.description}</td>
      <c:if test="${brand.status}==1">
        <td>启用</td>
      </c:if>
      <c:if test="${brand.status}!=1">
        <td>禁用</td>
      </c:if>
      <td><a href="#">修改</a><a href="#">删除</a></td>
    </tr>
  </c:forEach>
</table>
</body>
</html>
 
1.8、MVC模式和三层架构
- MVC是一种分层开发的模式,其中: 
  
- M: 
Model,业务模型,处理业务 - V: 
View,视图,界面展示 - C: 
Controller,控制器,处理请求,调用模型和视图 
 - M: 
 

- MVC好处 
  
- 职责单一,互不影响
 - 有利于分工协作
 - 有利于组件重用
 
 

- 数据访问层:对数据库的CRUD基本操作
 - 业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能
 - 表现层:接收请求,封装数据,调用业务逻辑层,响应数据
 

二、介于三层框架下的案例
2.1、准备环境

2.2、查询所有

2.3、添加

2.4、修改
2.4.1、修改-回显数据

- 注意: 
  
- SQL语句不要写错
 - JSTL语句不要写错
 
 
2.4.2、修改-修改数据

2.5、删除
Dao层:
void delete(Brand brand)
 
Service层
//调用brandMapper
void delete(Brand brand)
 
web层
- 接收数据,找到要删除的数据
 - 调用Service 层的
delete方法 - 重新加载数据
 
三、会话跟踪技术
3.1、会话跟踪技术概述
-  
会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
 -  
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
 -  
HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享
 -  
实现方式:
- 客户端会话跟踪技术:Cookie
 - 服务端会话跟踪技术:Session
 
 

3.2、Cookie 基本使用
-  
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
 -  
Cookie基本使用
 -  
发送Cookie
- 创建Cookie对象,设置数据
 
Cookie cookie = new Cookie("key" ,"value");- 发送Cookie到客户端:使用response对象
 
response.addCookie(cookie); -  
获取Cookie
- 获取客户端携带的所有Cookie,使用request对象
 
Cookie[] cookies = request.getCookies();- 遍历数组,获取每一个Cookie对象:for
 - 使用Cookie对象方法获取数据
 
cookie.getName();cookie.getValue(); 
代码演示
//发送Cookie
package com.Smulll.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/CookieServletDemo1")
public class CookieServletDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("username", "zhangsan");
        resp.addCookie(cookie);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
 
//获取Cookie
package com.Smulll.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/CookieServletDemo2")
public class CookieServletDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if ("username".equals(name)){
                String value = cookie.getValue();
                System.out.println(name+":"+value);
                break;
            }
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
 
3.3、Cookie原理
- Cookie的实现是基于HTTP协议的 
  
- 响应头: set-cookie
 - 请求头: cookie
 
 

3.4、Cookie细节
-  
Cookie存活时间
- 默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
 - setMaxAge(int seconds):设置Cookie存活时间 
    
- 正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
 - 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
 - 零:删除对应Cookie
 
 
 -  
Cookie存储中文
- Cookie不能直接存储中文
 - 如果需要存储,则需要进行转码:URL编码
 
//编码 value = URLDecoder.decode(value,"UTF-8"); //解码 value = URLDecoder.decode(value,"UTF-8"); 
代码演示
package com.Smulll.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
@WebServlet("/CookieServletDemo1")
public class CookieServletDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String value = "张三";
        value = URLEncoder.encode(value, "UTF-8");
        //设置发送cookie
        Cookie cookie = new Cookie("username", value);
        //设置存活时间为1000秒
        cookie.setMaxAge(1000);
        resp.addCookie(cookie);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
 
//获取Cookie
package com.Smulll.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
@WebServlet("/CookieServletDemo2")
public class CookieServletDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if ("username".equals(name)){
                String value = cookie.getValue();
                value = URLDecoder.decode(value,"UTF-8");
                System.out.println(name+":"+value);
                break;
            }
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
 
3.5、Session 基本使用
- 服务端会话跟踪技术:将数据保存到服务端
 - JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能
 - 使用: 
  
- 获取Session对象
 
HttpSession session = request.getSession();- Session对象功能:
 
void setAttribute(String name, Object o):存储数据到session域中Object getAttribute(String name):根据key,获取值void removeAttribute(String name):根据key,删除该键值对
 
3.6、Session 原理
- Session是基于Cookie实现的
 

3.7、Session 使用细节
-  
Session钝化、活化:
- 服务器重启后,Session中的数据是否还在?
 - 钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
 - 活化:再次启动服务器后,从文件中加载数据到Session中
 
 -  
Seesion销毁:
- 默认情况下,无操作,30分钟自动销毁 
    
- 配置在web-xml文件中
 
<session-config> <session-timeout>30</session-timeout> </session-config> - 调用Session对象的
invalidate()方法

 
 - 默认情况下,无操作,30分钟自动销毁 
    
 
3.8、小结
- Cookie和Session都是完成一次会话内多次请求间数据共享的
 - 区别: 
  
- 存储位置:Cookie是将数据存储在客户端,Session将数据存储在服务端
 - 安全性:Cookie不安全,Session安全
 - 数据大小:Cookie最大3KB,Session无大小限制
 - 存储时间:Cookie可以长期存储,Session默认30分钟
 - 服务器性能:Cookie不占服务器资源,Session占用服务器资源
 
 
四、会话跟踪-登录注册案例
4.1、需求说明
- 完成用户登录功能,如果用户勾选“记住用户”,则下次访问登录页面自动填充用户名密码
 - 完成注册功能,并实现验证码功能
 

4.2、用户登录

4.3、记住用户
- 如果用户勾选“记住用户”,则下次访问登陆页面自动填充用户名密码
 - 如何自动填充用户名和密码? 
  
- 将用户名和密码写入Cookie中,并且持久化存储Cookie,下次访问浏览器会自动携带Cookie
 - 在页面获取Cookie数据后,设置到用户名和密码框中
 
 
${cookie.key.value} //key指存储在cookie中的键名称
 
- 何时写Cookie? 
  
- 登录成功
 - 用户勾选记住用户复选框


 
 
4.4、注册用户
- 注册功能:保存用户信息到数据库
 

4.5、验证码-展示&校验
-  
验证码功能:
- 展示验证码:展示验证码图片,并可以点击切换
 - 校验验证码:验证码填写不正确,则注册失败
 
 -  
验证码就是使用Java代码生成的一张图片
 -  
验证码作用:防止机器自动注册,攻击服务器
 -  
校验验证码
- 判断程序生成的验证码和用户输入的验证码是否一样,如果不一样,则阻止注册
 - 验证码图片访问和提交注册表单是两次请求,所以要将程序生成的验证码存入Session中
 
 

 总结:
- 这次练习相比于上次的项目小练习就少了很多错误
 - 要点: 
  
- SQL语句的书写要准确无误
 - 路径地址不能少了
/号 - 类的方法不要快速的补全而忽略的方法是否正确
 
 



















