【Java WEB】Cookie&Session&JSP

个人主页:Hello Code.
本文专栏:《Java WEB从入门到实战》
Java WEB完整内容请点击前往Java WEB从入门到实战 查看
如有问题,欢迎指正,一起学习~~



Cookie

会话

  • 会话:浏览器和服务器之间的多次请求和响应
  • 为了实现一些功能,浏览器和服务器之间可能会产生多次的请求和响应,从浏览器访问服务器开始,到访问服务器结束(关闭浏览器、到了过期时间)。这期间产生的多次请求和响应加在一起就称之为浏览器和服务器之间的一次会话
  • 会话过程所产生的一些数据,可以通过会话技术(Cookie 和 Session)保存。

概述

  • Cookie: 客户端会话管理技术
    把要共享的数据保存到客户端
    每次请求时,把会话信息带到服务器端,从而实现多次请求的数据共享
  • 作用:可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率
  • 特点:
    • 是一个普通的Java类
    • 两个必须属性:name 和value
    • 发送:HttpServletResponse.addCookie(Cookie对象)
    • 每个网站最多20个Cookie,浏览器存储的Cookie总数不大于300个,每个Cookie大小限制在4kb
    • 获取所有Cookie对象:HttpServletRequest.getCookie()

Cookie属性

属性名 作用 是否重要
name Cookie的名称 必须属性
value Cookie的值(不支持中文) 必须属性
path Cookie的路径 重要
domain Cookie的域名 重要
maxAge Cookie的存活时间(s) 重要
version Cookie的版本号 不重要
comment Cookie的描述 不重要

方法

方法名 作用
Cookie(String name, String value) 构造方法创建对象
属性对应的set和get方法 赋值和获取值(name有final修饰,无set方法)
  • 向客户端添加Cookie:void HttpServletResponse.addCookie(Cookie cookie)
  • 获取所有的Cookie:Cookie[] HttpServletRequest.getCookies()

练习

  • 需求说明:通过Cookie记录最后访问时间,并在浏览器上显示出来
  • 最终目的:掌握Cookie的基本使用,从创建到添加客户端,再到从服务器端获取
  • 实现步骤
    1. 通过响应对象写出一个提示信息
    2. 创建Cookie对象,指定name和value
    3. 设置Cookie最大存活时间
    4. 通过响应对象将Cookie对象添加到客户端
    5. 通过请求对象获取Cookie对象
    6. 将Cookie对象中的访问时间写出
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
	// 通过响应对象写出一个提示信息
	resp.setContentType("text/html;charset=UTF-8");
	PrintWriter pw = resp.getWriter();
	pw.write("您的最后访问时间为:");
	pw.write("<br>");
	// 创建Cookie对象,指定name和value
	Cookie cookie = new Cookie("time", System.currentTimeMillis()+"");
	// 设置Cookie最大存活时间
	cookie.setMaxAge(3600);
	// 通过响应对象将Cookie对象添加到客户端
	resp.addCookie(cookie);
	// 通过请求对象获取Cookie对象
	Cookie[] cookies = req.getCookies();
	// 将Cookie对象中的访问时间写出
	for(Cookie ck : cookies){
    
    
		if("time".equals(ck.getName())){
    
    
			String value = ck.getValue();
			// 格式化时间
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String lastTime = sdf.format(new Date(Long.parseLong(value)));
			pw.write(lastTime);
		}
	}
}

注意事项

  • 数量限制
    每个网站最多只能用20个Cookie,且大小不能超过4kb,所有网站的Cookie总数不超过300个
  • 名称限制
    Cookie的名称只能包含ASCII码表中的字母、数字字符。不能包含逗号、分号、空格,不能以$开头。
    Cookie的值不支持中文
  • 存活时间限制setMaxAge()方法接收数字
    负整数:当前会话有效,浏览器关闭则清除(默认)
    0:立即清除
    正整数:以秒为单位设置存活时间
  • 访问路径限制
    取自第一次访问的资源路径前缀
    只要以这个前缀开头(包括子级路径)就能获取到,反之获取不到
    设置路径:setPath()方法设置指定路径

Session

  • HttpSession:服务器端会话管理技术
    • 本质也是采用客户端会话管理技术
    • 只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中。
    • 每次请求时,会将特殊标识带到服务器端,根据这个标识来找到对应的内存空间,从而实现数据共享
    • 是Servlet规范中四大域对象之一的会话域对象
  • 作用:可以实现数据共享
    域对象 功能 作用
    ServletContext 应用域 在整个应用之间实现数据共享
    ServletRequest 请求域 在当前的请求或请求转发之间实现数据共享
    HttpSession 会话域 在当前会话范围之间实现数据共享

常用方法

返回值 方法名 说明
void setAttribute(String name, Object value) 设置共享数据
Object getAttribute(String name) 获取共享数据
void removeAttribute(String name) 移除共享数据
String getId() 获取唯一标识名称
void Invalidate() 让session立即失效

对象获取

HttpSession 是一个接口,对应的实现类对象是通过HttpServletRequest 对象来获取

返回值 方法名 说明
HttpSession getSession() 获取HttpSession对象
HttpSession getSession(boolean create) 获取HttpSession对象,未获取到是否自动创建(默认true)

练习

  • 需求说明:通过第一个Servlet 设置共享数据用户名,并在第二个Servlet 获取到
  • 最终目的:掌握HttpSession 的基本使用,如何获取和使用
  • 实现步骤
    1. 在第一个 Servlet 中获取请求的用户名
    2. 获取 HttpSession 对象
    3. 将用户名设置到共享数据中
    4. 在第二个 Servlet 中获取 HttpSession 对象
    5. 获取共享数据用户名
    6. 将获取到的用户名响应给客户端浏览器
// Session01
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        // 在第一个 Servlet 中获取请求的用户名
        String username = req.getParameter("username");
        // 获取 HttpSession 对象
        HttpSession session = req.getSession();
        // 将用户名设置到共享数据中
        session.setAttribute("username",username);
    }
// session02
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        // 在第二个 Servlet 中获取 HttpSession 对象
        HttpSession session = req.getSession();
        // 获取共享数据用户名
        Object username = session.getAttribute("username");
        // 将获取到的用户名响应给客户端浏览器
        PrintWriter pw = resp.getWriter();
        pw.write(username+"");
    }

注意事项

  • 唯一标识的查看:借助浏览器开发者工具
  • 浏览器禁用Cookie
    方式一:通过提示信息告知用户,大部分网站采用的解决方式【推荐】
    方式二:通过resp.enconeURL方法实现url重写(地址栏拼接jsessionid)【了解】
  • 钝化和活化
    • 钝化:序列化。把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上
    • 活化:相反的状态
    • 钝化时间
      第一种情况: 当访问量很大时,服务器会根据getLastAccessTime 来进行排序,对长时间不用,但还没到过期时间的HttpSession进行序列化
      第二种情况: 当服务器进行重启的时候,为了保持客户HttpSession 中的数据,也要对其进行序列化

    HttpSession 的序列化由服务器自动完成,我们无需关心


JSP

  • JSP(Java Server Pages):是一种动态网页技术标准
  • JSP 部署在服务器上,可以处理客户端发送的请求,并根据请求内容动态的生成 HTML、XML 或其他格式文档的 Web网页,然后再响应给客户端。
  • Jsp 是基于Java 语言的,它的本质就是 Servlet
类别 使用场景
HTML 开发静态资源,无法添加动态资源
CSS 美化页面
JavaScript 给网页添加一些动态效果
Servlet 编写Java 代码,实现后台功能处理
JSP 包含了显示页面技术,也具备Java代码功能

快速入门

  1. 创建一个web项目
  2. 在web 目录下创建一个 index.jsp 文件
  3. 在文件中写一句内容为:这是我的第一个jsp
  4. 部署并启动项目
  5. 通过浏览器测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    第一个jsp
</body>
</html>

执行过程

  1. 客户端浏览器发送请求到Tomcat 服务器
  2. Tomcat 服务器解析请求地址
  3. 找到具体的应用
  4. 找到对应的jsp文件
  5. 将jsp文件翻译为.java的文件
  6. 编译Java文件
  7. 响应给客户端

文件内容介绍

  • 生成的Java 文件目录
    继承自 HttpJspBase类,而HttpJspBase继承自 HttpServlet(JSP本质上就是一个 Servlet)
    jsp显示页面本质上就是通过获取输出流对象并通过write写出

语法

  • JSP注释:<%-- 注释的内容 --%>
  • Java代码块:<% Java代码 %>
  • JSP表达式:<%=表达式%>
  • JSP声明:<%! 声明变量或方法 %>

System.out.println():普通输出语句,输出在控制台上
out.println():JspWriter 对象,将内容输出在浏览器页面上,不会自动换行
<%="要输出的内容"%>就相当于out.println("要输出的内容")
在声明中,如果加!,代表声明的是成员变量;如果不加!,代表声明的是局部变量;如果是声明方法,就必须加!

指令

  • page 指令:<%@ page 属性名=属性值 属性名=属性值... %>
    属性名 作用
    contentType 响应正文支持的类型和设置编码格式
    language 使用的语言,默认是Java
    errorPage 当前页面出现异常后跳转的页面
    isErrorPage 是否抓住异常,如果为true则页面中就可以使用异常对象,默认是false
    import 导包 import= “java.util.ArrayList”
    session 是否创建 HttpSession 对象,默认是true
    buffer 设定 JspWriter 输出jsp内容缓存的大小,默认8kb
    pageEncoding 翻译jsp时所用的编码格式
    isEIgnored 是否忽略EL表达式,默认是false
  • include 指令:可以包含其他页面
    <%@ include file=包含的页面 %>
  • taglib 指令:可以引入外部标签库
    <%@ taglib uri=标签库的地址 prefix=前缀名称 %>

注意事项

  • 九大隐式对象(不用创建,可以直接使用)
    隐式对象名称 代表实际对象
    request javax.servlet.http.HttpServletRequest
    response javax.servlet.http.HttpServletResponse
    session javax.servlet.http.HttpSession
    application javax.servlet.ServletContext
    page java.lang.Object
    config javax.servlet.ServletConfig
    exception java.lang.Throwable
    out javax.servlet.jsp.JspWriter
    pageContext javax.servlet.jsp.PageContext
  • PageContext 对象
    • 是 JSP 独有的, Servlet 中没有
    • 是四大域对象之一的页面域对象,还可以操作其他三个域对象中的属性
    • 还可以获取其他八个隐式对象
    • 生命周期是随着 JSP 的创建而存在,随着 JSP 的结束而消失。每个JSP 页面都有一个 PageContext 对象

四大域对象

域对象名称 范围 级别 备注
PageContext 页面范围 最小,只能在当前页面使用 因范围太小,开发中用的很少
ServletRequest 请求范围 一次请求或当前请求转发用 请求转发之后,再次转发时请求域丢失
HttpSession 会话范围 多次请求数据共享时使用 多次请求共享数据,但不同的客户端不能共享
ServletContext 应用范围 最大,整个应用都可以使用 尽量少用,如果对数据有修改需要做同步处理

MVC模型

  • M(Model):模型。 用于封装数据,封装的是数据模型
  • V(View):视图。 用于显示数据,动态资源用 JSP页面,静态资源用 HTML 页面
  • C(Controller):控制器。 用于处理请求和响应,例如 Servlet

在这里插入图片描述


学生管理系统3

登录功能

  1. 创建一个web目录
  2. 在web目录下创建一个index.jsp
  3. 在页面中获取会话域中的用户名,获取到了就显示添加和查看功能的超链接,没获取到就显示登录功能的超链接
  4. 在web目录下创建一个login.jsp。实现登录页面
  5. 创建 LoginServlet,获取用户名和密码
  6. 如果用户名为空,则重定向到登录页面
  7. 如果不为空,将用户名添加到会话域中,再重定向到首页
<%-- login.jsp --%>
<%--
  Created by IntelliJ IDEA.
  User: lihao
  Date: 2022/2/24
  Time: 20:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<h1>学生信息管理系统--登录</h1>
<hr>
<form action="/login" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <button type="submit">登录</button>
</form>
</body>
</html>
// login.java
package studentServlet;

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 {
    
    
        HttpSession session = req.getSession();
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        resp.setContentType("text/html;charset=UTF-8");
        if(null == username || "".equals(username)){
    
    
            resp.getWriter().write("账号不能为空,请重新输入(2s后返回...)");
            resp.setHeader("Refresh","2;URL=/login.jsp");
        }else{
    
    
            if("admin".equals(username) && "abc123".equals(password)){
    
    
                session.setAttribute("username",username);
                resp.sendRedirect("/index.jsp");
            }else{
    
    
                resp.getWriter().write("账号密码不正确,请重新输入(2s后返回...)");
                resp.setHeader("Refresh","2;URL=/login.jsp");
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}
<%-- index.jsp --%>
<%--
  Created by IntelliJ IDEA.
  User: lihao
  Date: 2022/2/24
  Time: 19:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学生信息管理系统</title>
</head>
<body>
    <h1>学生信息管理系统</h1>
    <hr>
    <% if(session.getAttribute("username") == null){ %>
    <a href="/login.jsp">请登录</a>
    <% } else { %>
    <a href="/add.jsp">添加学生信息</a>
    <a href="/list">查看学生信息</a>
    <% } %>
</body>
</html>
<%-- list.jsp --%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="studentServlet.bean.Student" %>
<%--
  Created by IntelliJ IDEA.
  User: lihao
  Date: 2022/2/24
  Time: 20:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>查看学生</title>
</head>
<body>
    <table width="600px" border="1px" align="center">
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>成绩</th>
        </tr>
        <%
            ArrayList<Student> students = (ArrayList<Student>) session.getAttribute("students");
            for(Student stu : students){
        %>
            <tr>
                <td><%=stu.getUsername()%></td>
                <td><%=stu.getAge()%></td>
                <td><%=stu.getScore()%></td>
            </tr>
        <% } %>
    </table>
</body>
</html>
// list.java
package studentServlet;

import studentServlet.bean.Student;

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.*;
import java.util.ArrayList;
@WebServlet("/list")
public class list extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        BufferedReader br = new BufferedReader(new FileReader("E:\\Java\\code\\StudentServlet\\stu.txt"));
        ArrayList<Student> list = new ArrayList<>();
        String str;
        while((str = br.readLine()) != null){
    
    
            String[] split = str.split(",");
            Student stu = new Student(split[0], Integer.parseInt(split[1]), Integer.parseInt(split[2]));
            list.add(stu);
        }
        req.getSession().setAttribute("students",list);
        resp.sendRedirect("/list.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}

推荐阅读:【Java WEB】EL表达式&Filter&Listener

猜你喜欢

转载自blog.csdn.net/qq_24980365/article/details/123547415
今日推荐