Cookie&Session&Jsp总结
知识点梳理
Cookie&Session&Jsp
1 会话技术
1.1 会话管理概述
1.1.1 会话技术介绍
会话:浏览器和服务器之间的多次请求和响应 (一次对话)
为了实现一些功能,浏览器和服务器之间可能会产生多次的请求和响应
从浏览器访问服务器开始,到访问服务器结束(关闭浏览器、到了过期时间)
这期间产生的多次请求和响应加在一起就称之为浏览器和服务器之间的一次会话
这里的会话,指的是web开发中的一次通话过程,当打开浏览器,访问网站地址后,会话开始,当关闭浏览器(或者到了过期时间),会话结束
会话过程中所产生的一些数据,可以通过会话技术( Cookie 和 Session )保存
播仔,登陆了黑马论坛(右上角显示:用户名:小播)
然后点击“Java学科板块” , 打开新界面“Java学科板块”,在这里发帖 (在这个界面依然保持登陆状态)
接下来又点击“”前端学科板块“,打开新界面”前端学科板块“,在这里发帖(在这个界面依然保持登陆状态)
在一次登陆之后,然后打开很对新界面,依然能够保持登陆,就是通过会话技术实现的
cookie&session到底是干嘛用的呢?
存储数据,用户登录状态
因为在网站中,有很多界面都是需要登录之后才能操作,为了避免重复登录,我们会在第一次登录成功之后将用户的登录状态存储到会话技术中(cookie,session)
1.1.2 会话管理分类
Cookie:客户端会话管理技术
把要共享的数据保存到客户端。
每次请求时,把会话信息带到服务器端,从而实现多次请求的数据共享!
Session:服务器端会话管理技术
本质也是采用客户端会话管理技术。
只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中。
每次请求时,会将特殊标识带到服务器端,根据这个标识来找到对应的内存空间,从而实现数据共享!
1.2 客户端会话管理技术 ***
1.2.1 Cookie概述
1)Cookie的介绍
Cookie:客户端会话管理技术
把要共享的数据保存到客户端(浏览器)
每次请求时,浏览器会把会话信息带到服务器端,从而实现多次请求的数据共享
作用:可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率!
Cookie API 介绍
2)Cookie的常见属性
属性名称 | 属性作用 | 是否重要 |
---|---|---|
name | cookie的名称 | 必要属性 |
value | cookie的值(不能是中文) | 必要属性 |
path | cookie的路径 | 重要 |
domain | cookie的域名 | 重要 |
maxAge | cookie的生存时间 | 重要 |
version | cookie的版本号 | 不重要 |
comment | cookie的说明 | 不重要 |
细节
Cookie有大小,个数限制。每个网站最多只能存20个cookie,且大小不能超过4kb。同时,所有网站的cookie总数不超过300个。
当删除Cookie时,设置maxAge值为0。当不设置maxAge时,使用的是浏览器的内存,当关闭浏览器之后,cookie将丢失。设置了此值,就会保存成缓存文件(值必须是大于0的,以秒为单位)。
3)Cookie的方法和添加获取
cookie的方法
Cookie源码
添加:HttpServletResponse对象中提供了addCookie()方法
获取:HttpServletRequest对象中提供了getCookies()方法
补充:为啥是响应对象添加cookie,而获取对象是请求对象?
因为,cookie是通过服务器端代码将数据保存在浏览器,所以服务器让浏览器做一件事情,肯定是通过响应
而在浏览器存储的数据,要想告诉服务器都有什么,那肯定是通过请求
1.2.2 Cookie的使用
需求说明
通过 Cookie 记录最后访问时间,并在浏览器上显示出来
最终目的
掌握 Cookie 的基本使用,从创建到保存到客户端,再到从服务器端获取
实现步骤
通过响应对象写出一个提示信息
创建 Cookie 对象,指定 name 和 value
设置 Cookie 最大存活时间
通过响应对象将 Cookie 对象添加到客户端
通过请求对象获取 Cookie 对象
将 Cookie 对象中的访问时间写出、
案例:新建项目cookie_demo,配置虚拟目录/cookie,新建类com.itheima.servlet.ServletDemo01
package com.itheima.servlet;
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.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
Cookie的使用
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
//1.通过响应对象写出提示信息
PrintWriter pw = resp.getWriter();
pw.write("欢迎访问本网站,您的最后访问时间为:<br>");
//2.创建Cookie对象,用于记录最后访问时间
Cookie cookie = new Cookie("time",System.currentTimeMillis()+"");
//3.设置最大存活时间(单位s)
cookie.setMaxAge(3600);
//4.将cookie对象添加到客户端
resp.addCookie(cookie);
//5.获取cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("time".equals(c.getName())) {
//6.获取cookie对象中的value,进行写出
String value = c.getValue();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
pw.write(sdf.format(new Date(Long.parseLong(value))));
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}注意:这里我们为了节省时间,所以在一个Servlet中设置之后,立马又获取了
其实可以在一个Servlet中设置,另一个Servlet中获取
访问
在headers中看到的Data是07:23,这个是xx 时间,我们是东八区的,所以+8小时
然后set-cookie中可以看到,设置的cookie是time=xxx
Max-age是1小时
Expires过期时间是08:23
cookie文件
cookie是保存在浏览器中的,那浏览器将cookie信息保存到缓存文件中了
itcast@localhost/cookie/
本机用户名@本网站ip地址/cookie/
1.2.3 Cookie的使用细节
1) 细节介绍
数量限制
每个网站最多只能有 20 个 Cookie,且大小不能超过 4KB。所有网站的 Cookie 总数不能超过 300 个。
名称限制
Cookie 的名称只能包含 ASCCI 码表中的字母、数字字符。不能包含逗号、分号、空格,不能以 $ 开头。
Cookie 的值不支持中文。
存活时间限制 setMaxAge() 方法接收数字
负整数:当前会话有效,浏览器关闭则清除。
0:立即清除。
正整数:以秒为单位设置存活时间。
访问路径限制
默认路径:取自第一次访问的资源路径前缀。只要以这个路径开头就能访问到
设置路径:setPath() 方法设置指定路径
2) 存活时间案例 ***
在上个案例中修改代码
//3.设置最大存活时间
//cookie.setMaxAge(3600);
cookie.setMaxAge(0); // 立即清除访问
3) 访问路径限制案例
新建ServletDemo02:设置cookie
package com.itheima.servlet;
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;
/*
Cookie的路径限制
取自第一次访问的资源路径前缀
只要以这个前缀为开头(包括子级路径)。获取到
反之获取不到
*/
@WebServlet("/servlet/servletDemo02")
public class ServletDemo02 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie并添加
Cookie cookie = new Cookie("username","zhangsan");
cookie.setMaxAge(3600);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
新建ServletDemo03:获取cookie
package com.itheima.servlet;
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;
/*
Cookie的路径限制
*/
@WebServlet("/servlet/servletDemo03")
public class ServletDemo03 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("username".equals(c.getName())) {
String value = c.getValue();
resp.getWriter().write(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}新建ServletDemo04:获取cookie
package com.itheima.servlet;
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;
/*
Cookie的路径限制
*/
@WebServlet("/servlet/aaa/servletDemo04")
public class ServletDemo04 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("username".equals(c.getName())) {
String value = c.getValue();
resp.getWriter().write(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
新建ServletDemo05:获取cookie
package com.itheima.servlet;
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;
/*
Cookie的路径限制
*/
@WebServlet("/bbb/servletDemo05")
public class ServletDemo05 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("username".equals(c.getName())) {
String value = c.getValue();
resp.getWriter().write(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}访问
总结:Cookie的路径限制
取自第一次访问的资源路径前缀
只要以这个前缀为开头(包括子级路径)就可以获取到
反之获取不到
1.3 服务端会话管理概述 ***
1.3.1 HttpSession概述
1)HttpSession介绍
HttpSession:服务器端会话管理技术
本质也是采用客户端会话管理技术
只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中
每次请求时,会将特殊标识带到服务器端,根据这个标识来找到对应的内存空间,从而实现数据共享
是 Servlet 规范中四大域对象之一的会话域对象
作用:可以实现数据共享
为了防止在 一次会话中,让用户多次登录(用户登录状态)
域对象API
补充:
HttpSession,它虽然是服务端会话管理技术的对象,但它本质仍是一个Cookie
是一个由服务器自动创建的特殊的Cookie,Cookie的名称就是JSESSIONID,Cookie的值是服务器分配的一个唯一的标识
当我们使用HttpSession时,浏览器在没有禁用Cookie的情况下,都会把这个Cookie带到服务器端,然后根据唯一标识去查找对应的HttpSession对象,找到了,我们就可以直接使用了
2)HttpSession的常用方法
3)HttpSession的获取
获取HttpSession是通过HttpServletRequest接口中的两个方法获取的,如下图所示:
这两个方法的区别:
1.3.2 HttpSession的使用
需求说明
通过第一个 Servlet 设置共享数据用户名,并在第二个 Servlet 获取到
最终目的
掌握 HttpSession 的基本使用,如何获取和使用
实现步骤
在第一个 Servlet 中获取请求的用户名
获取 HttpSession 对象
将用户名设置到共享数据中
在第二个 Servlet 中获取 HttpSession 对象
获取共享数据用户名
将获取到用户名响应给客户端浏览器
案例:
新建项目session_demo,虚拟目录/session
新建com.itheima.servlet.ServletDemo01:设置共享数据
package com.itheima.servlet;
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;
/*
Session的基本使用
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求的用户名
String username = req.getParameter("username");
//2.获取HttpSession的对象
HttpSession session = req.getSession();
//3.将用户名信息添加到共享数据中
session.setAttribute("username",username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
新建ServletDemo02:获取共享数据
package com.itheima.servlet;
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;
/*
Session的基本使用
*/
@WebServlet("/servletDemo02")
public class ServletDemo02 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取HttpSession对象
HttpSession session = req.getSession();
System.out.println(session);
System.out.println(session.getId());
//2.获取共享数据
Object username = session.getAttribute("username");
//3.将数据响应给浏览器
resp.getWriter().write(username+"");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
访问
验证:demo1和demo2的session是否是同一个对象
//两个代码中都添加如下log
System.out.println(session);
System.out.println(session.getId());访问:分别访问两个demo,发现一致
1.3.3 细节 (了解)
1) 唯一标识查看
唯一标识查看(刚刚是打印出来了,其实可以通过Network查看)
2) 禁用cookie
浏览器禁用 Cookie之后如何使用session?(用户可以设置浏览器来禁止Cookie的使用)
方式一:通过提示信息告知用户,大部分网站采用的解决方式。(推荐) ***
方式二:访问时拼接 jsessionid 标识,通过 encodeURL() 方法重写地址。(了解)
如何禁用cookie?
案例:新建ServletDemo03
package com.itheima.servlet;
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;
/*
Cookie的禁用
*/
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取HttpSession对象
HttpSession session = req.getSession();
System.out.println(session);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
访问
在demo1中,创建了一个session
在demo3中,因为禁用cookie了,sessionid没有传递过来,所以又创建了一个新session
所以俩session不一致
为了能够看到效果,我们修改一下代码
修改
HttpSession session = req.getSession(false);//改为false,如果没有找到session也不创建
访问
增加解决呢?看下天猫,也是简单的给出了提升
我们也增加提示
if(session == null) {
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("为了不影响正常的使用,请不要禁用浏览器的Cookie~");
}访问
弹框是需要用到js,后续才学习
方式二:访问时拼接 jsessionid 标识,通过 encodeURL() 方法重写地址
//修改demo1
//实现url重写 相当于在地址栏后面拼接了一个jsessionid(encodeURL自动会给路径后添加jsessionid)
resp.getWriter().write("<a href='"+resp.encodeURL("http://localhost:8080/session/servletDemo03")+"'>go servletDemo03</a>");
访问
方式二不推荐,因为每次跳转都的做url重新,比较麻烦
3) HttpSession的钝化和活化
什么是钝化和活化
钝化:序列化。把长时间不用,但还不到过期时间的 HttpSession 进行序列化,写到磁盘上
活化:相反的状态
何时钝化
第一种情况:当访问量很大时,服务器会根据 getLastAccessTime 来进行排序,
对长时间不用,但是还没到过期时间的 HttpSession 进行序列化。
第二种情况:当服务器进行重启的时候,为了保持客户 HttpSession 中的数据,也要对其进行序列化
注意
HttpSession 的序列化由服务器自动完成,我们无需关心
2 页面技术
2.1 JSP基础
2.1.1 JSP介绍***
JSP(Java Server Pages):是一种动态网页技术标准
JSP 部署在服务器上,可以处理客户端发送的请求,并根据请求内容动态的生成 HTML、XML 或其他格式文档的 Web 网页,然后再响应给客户端
JSP 是基于 Java 语言的,它的本质就是 Servlet
所学习的相关资源总结(JavaScript后续学习)
动态资源:会变化的数据
动态效果:例如界面上的一些特效,弹框
2.1.2 JSP快速入门
创建一个 web 项目:jsp_demo,虚拟目录/jsp
在 web 目录下创建一个 index.jsp 文件
默认就有一个index.jsp
在文件中写一句内容为:这是我的第一个jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP</title>
</head>
<body>
<h1>这是我的第一个jsp</h1>
</body>
</html>部署并启动项目
通过浏览器测试
2.1.3 JSP的执行过程 ***
执行过程图
明确JSP就是一个Servlet,是一个特殊的Servlet
其实在第五步,翻译jsp文件,就是将jsp翻译成了一个Servlet
2.1.4 JSP的.java文件内容分析
生成的 java 文件目录
C:\Users\itcast.IntelliJIdea2018.3\system\tomcat_ideaproject\work\Catalina\localhost\jsp\org\apache\jsp
JSP 本质就是一个 Servlet
补充:HttpJspBase.class反编译查看
2.2 JSP应用
2.2.1 JSP语法
JSP 注释
<%-- 注释的内容 --%>
Java 代码块
<% Java代码 %>
JSP 表达式
<%=表达式%>
JSP 声明
<%! 声明变量或方法 %>
案例:新建web/jsp语法.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp语法</title>
</head>
<body>
<%--
1. 这是注释
--%> <%--
2.java代码块 ***
System.out.println("Hello JSP"); 普通输出语句,输出在控制台
out.println("Hello JSP");out是JspWriter对象,输出在页面上
--%>
<%
System.out.println("Hello JSP");
out.println("Hello JSP<br>");
String str = "hello<br>";
out.println(str);
%> <%--
3.jsp表达式 *** 语法糖:某种语法的简写形式
<%="Hello"%> 相当于 out.println("Hello");
--%>
<%="Hello<br>"%> <%--
4.jsp中的声明(变量或方法)
如果加! 代表的是声明的是成员变量(service中的局部变量)
如果不加! 代表的是声明的是局部变量 ***
--%>
<%! String s = "abc";%>
<% String s = "def";%>
<%=s%>
<%! public void getSum(){}%>
<%--<% public void getSum2(){}%> 这个是局部方法,相当于是在getSum里再声明方法,所以不允许--%>
</body>
</html>
2.2.2 JSP指令
1)page指令
语法:<%@ page 属性名=属性值 属性名=属性值 … %>
language: 告知引擎,脚本使用的是java,默认是java,支持java。不写也行。
import:告知引擎,导入哪些包(类)。 ***
注意:引擎会自动导入:java.lang.*,javax.servlet.*,javax.servlet.http.*,javax.servlet.jsp.
导入的形式:
<%@page import=”java.util.Date,java.util.UUID”%>或者:
<%@page import=”java.util.Date”%>
<%@page import=”java.util.UUID”%> 用Eclipse:Alt+/ 自动导入
contentType:告知引擎,响应正文的MIME类型。contentType="text/html;charset=UTF-8"
相当于response.setContentType("text/html;charset=UTF-8");
案例:新建jsp指令.jsp
<%--
1.page指令
--%>
<%@ page import="java.util.ArrayList"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="/error.jsp" %>
<html>
<head>
<title>jsp指令</title>
</head>
<body>
<% int result = 1 / 0; %>
<% ArrayList list = new ArrayList() %>
</body>
</html>新建error.jsp:上述代码中1/0是错误的语法,所以会跳转到errorPage指定的error.jsp界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>自定义错误页面</title>
</head>
<body>
不好意思,出错了~~~
</body>
</html>
2)include指令
通过该指令,可以包含其他页面
语法格式:
<%@include file="" %>
属性:file,以/开头,就代表当前应用
案例
<%--
1.page指令
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="/error.jsp" %> <%--
2.include指令
--%>
<%@ include file="/include.jsp"%>
<html>
<head>
<title>jsp指令</title>
</head>
<body>
<%--<% int result = 1 / 0; %>--%>
<%=s%> <%--这里用的s是include.jsp中的--%>
</body>
</html>新建include.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>被包含的页面</title>
</head>
<body>
<% String s = "Hello"; %>
</body>
</html>访问
3)taglib指令 ***
该指令用于引入外部标签库,html标签和jsp标签不用引入
语法格式:
<%taglib uri="" prefix=""%>
属性:
uri:外部标签的URI地址
prefix:使用标签时的前缀
tag:标签,lib:library库,prefix:前缀
2.2.3 JSP细节
1)九大隐式对象
什么是隐式对象呢?
它指的是在jsp中,可以不声明就直接使用的对象
它只存在于jsp中,因为java类中的变量必须要先声明再使用
其实jsp中的隐式对象也并非是未声明,只是它是在翻译成.java文件时声明的
所以我们在jsp中可以直接使用
隐式对象名称 | 类型 | 备注 |
---|---|---|
request | javax.servlet.http.HttpServletRequest | 请求对象 |
response | javax.servlet.http.HttpServletResponse | 相应对象 |
session | javax.servlet.http.HttpSession | Page指令可以控制开关 |
application | javax.servlet.ServletContext | 应用域对象 |
page | Java.lang.Object | 当前jsp对应的servlet引用实例 |
config | javax.servlet.ServletConfig | Servlet配置对象 |
exception | java.lang.Throwable | 异常对象 |
out | javax.servlet.jsp.JspWriter | 字符输出流,相当于printwriter |
pageContext | javax.servlet.jsp.PageContext | 页面域对象 |
2)PageContext对象
简介
是 JSP 独有的,Servlet 中没有
是四大域对象之一的页面域对象,还可以操作其他三个域对象中的属性(应用域,会话域,请求域)
还可以获取其他八个隐式对象
生命周期是随着 JSP 的创建而存在,随着 JSP 的结束而消失。每个 JSP 页面都有一个 PageContext对象
常用方法
在上图中,同学们发现没有页面域操作的方法,其实是定义在了PageContext的父类JspContext中,如下图所示:
3)四大域对象
域对象名称 | 范围 | 级别 | 备注 |
---|---|---|---|
PageContext | 页面范围 | 最小,只能在当前页面用 | 因范围太小,开发中用的很少 |
ServletRequest*** | 请求范围 | 一次请求或当期请求转发用 | 当请求转发之后,再次转发时请求域丢失 |
HttpSession*** | 会话范围 | 多次请求数据共享时使用 | 多次请求共享数据,但不同的客户端不能共享 |
ServletContext | 应用范围 | 最大,整个应用都可以使用 | 尽量少用,如果对数据有修改需要做同步处理 |
2.2.4 JSP-MVC模型介绍 ***
M(Model):模型。用于封装数据,封装的是数据模型
V(View):视图。用于显示数据,动态资源用 JSP 页面,静态资源用 HTML 页面
C(Controller):控制器。用于处理请求和响应,例如 Servlet
图示
3 综合案例-学生管理系统升级 ***
3.1 案例效果介绍
3.2 登陆功能
创建一个 web 项目:student_manage,虚拟目录/stu
在 web 目录下创建一个 index.jsp(默认就有)
在页面中获取会话域中的用户名,获取到了就显示添加和查看功能的超链接,没获取到就显示登录功能的超链接
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生管理系统首页</title>
</head>
<body>
<%--
获取会话域中的数据
如果获取到了则显示添加和查看功能的超链接
如果没获取到则显示登录功能的超链接
--%>
<% Object username = session.getAttribute("username");
if(username == null) {
%>
<a href="/stu/login.jsp">请登录</a>
<%} else {%>
<a href="/stu/addStudent.jsp">添加学生</a>
<a href="/stu/listStudentServlet">查看学生</a>
<%}%>
</body>
</html>在 web 目录下创建一个 login.jsp:实现登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生登录</title>
</head>
<body>
<form action="/stu/loginStudentServlet" method="get" autocomplete="off">
姓名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
<button type="submit">登录</button>
</form>
</body>
</html>创建 LoginStudentServlet,获取用户名和密码
如果用户名为空,则重定向到登录页面
如果不为空,将用户名添加到会话域中,再重定向到首页
package com.itheima.servlet; 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("/loginStudentServlet")
public class LoginStudentServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password"); //2.判断用户名
if(username == null || "".equals(username)) {
//2.1用户名为空 重定向到登录页面
resp.sendRedirect("/stu/login.jsp");
return;
} //2.2用户名不为空 将用户名存入会话域中
req.getSession().setAttribute("username",username); //3.重定向到首页index.jsp
resp.sendRedirect("/stu/index.jsp");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
访问
3.3 添加功能
在 web 目录下创建一个 addStudent.jsp,实现添加学生的表单项
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加学生</title>
</head>
<body>
<form action="/stu/addStudentServlet" method="get" autocomplete="off">
学生姓名:<input type="text" name="username"> <br>
学生年龄:<input type="number" name="age"> <br>
学生成绩:<input type="number" name="score"> <br>
<button type="submit">保存</button>
</form>
</body>
</html>创建 AddStudentServlet,获取学生信息并保存到文件中
通过定时刷新功能 2 秒后跳转到首页
package com.itheima.servlet; import com.itheima.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.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException; /*
实现添加功能
*/
@WebServlet("/addStudentServlet")
public class AddStudentServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取表单中的数据
String username = req.getParameter("username");
String age = req.getParameter("age");
String score = req.getParameter("score"); //2.创建学生对象并赋值
Student stu = new Student();
stu.setUsername(username);
stu.setAge(Integer.parseInt(age));
stu.setScore(Integer.parseInt(score)); //3.将学生对象的数据保存到d:\\stu.txt文件中
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\stu.txt",true));
bw.write(stu.getUsername() + "," + stu.getAge() + "," + stu.getScore());
bw.newLine();
bw.close(); //4.通过定时刷新功能响应给浏览器
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("添加成功。2秒后自动跳转到首页...");
resp.setHeader("Refresh","2;URL=/stu/index.jsp");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}访问
3.4 查看功能
创建 ListStudentServlet,读取文件中的学生信息到集合中
将集合添加到会话域中
重定向到 listStudent.jsp 页面上
package com.itheima.servlet; import com.itheima.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.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList; /*
实现查看功能
*/
@WebServlet("/listStudentServlet")
public class ListStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.创建字符输入流对象,关联读取的文件
BufferedReader br = new BufferedReader(new FileReader("d:\\stu.txt")); //2.创建集合对象,用于保存Student对象
ArrayList<Student> list = new ArrayList<>(); //3.循环读取文件中的数据,将数据封装到Student对象中。再把多个学生对象添加到集合中
String line;
while((line = br.readLine()) != null) {
//张三,23,95
Student stu = new Student();
String[] arr = line.split(",");
stu.setUsername(arr[0]);
stu.setAge(Integer.parseInt(arr[1]));
stu.setScore(Integer.parseInt(arr[2]));
list.add(stu);
} //4.将集合对象存入会话域中
req.getSession().setAttribute("students",list); //5.重定向到学生列表页面
resp.sendRedirect("/stu/listStudent.jsp"); } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}在 web 目录下创建一个 listStudent.jsp
定义表格标签。在表格中获取会话域的集合数据,将数据显示在页面上
<%@ page import="com.itheima.bean.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>查看学生</title>
</head>
<body>
<table width="600px" border="1px">
<tr>
<th>学生姓名</th>
<th>学生年龄</th>
<th>学生成绩</th>
</tr>
<% ArrayList<Student> students = (ArrayList<Student>) session.getAttribute("students");
for(Student stu : students) {
%>
<tr align="center">
<td><%=stu.getUsername()%></td>
<td><%=stu.getAge()%></td>
<td><%=stu.getScore()%></td>
</tr>
<%}%>
</table>
</body>
</html>访问:点击查看学生,进入查看学生界面
Cookie&Session&Jsp总结的更多相关文章
- 会话技术: Cookie Session JSP
## Cookie A..概念:客户端会话技术,将数据保存到客户端 B.使用步骤: 1.创建Cookie对象,绑定数据 new Cookie(String name, String value) ...
- 中阶 d06.1 cookie && session && jsp介绍
##Cookie > 饼干. 其实是一份小数据, 是服务器给客户端,并且存储在客户端上的一份小数据 ### 应用场景 > 自动登录.浏览记录.购物车. ###为什么要有这个Cookie & ...
- Cookie&&Session&&jsp入门
会话技术 会话:一次会话中包含多次请求和响应. 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止 功能:在一次会话的范围内的多次请求间,共享数据 方式: 客户端会话技术:Coo ...
- Cookie/Session机制详解
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...
- [转]Cookie/Session机制详解
原文地址:http://blog.csdn.net/fangaoxin/article/details/6952954 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用 ...
- Servlet学习笔记(1)--第一个servlet&&三种状态对象(cookie,session,application)&&Servlet的生命周期
servlet的404错误困扰了两天,各种方法都试过了,翻书逛论坛终于把问题解决了,写此博客来纪念自己的第一个servlet经历. 下面我会将自己的编写第一个servlet的详细过程提供给初学者,大神 ...
- Cookie/Session机制具体解释
会话(Session)跟踪是Web程序中经常使用的技术,用来跟踪用户的整个会话.经常使用的会话跟踪技术是Cookie与Session.Cookie通过在client记录信息确定用户身份,Session ...
- 【转】Cookie/Session机制详解
Cookie/Session机制详解 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息 ...
- Cookie/Session机制详解(转载)
原文链接:http://blog.csdn.net/fangaoxin/article/details/6952954 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用 ...
随机推荐
- 超详细分析Bootloader到内核的启动流程(万字长文)
@ 目录 Bootloader启动流程分析 Bootloader第一阶段的功能 硬件设备初始化 为加载 Bootloader的第二阶段代码准备RAM空间(初始化内存空间) 复制 Bootloader的 ...
- [从源码学设计]蚂蚁金服SOFARegistry 之 自动调节间隔周期性任务
[从源码学设计]蚂蚁金服SOFARegistry 之 自动调节间隔周期性任务 目录 [从源码学设计]蚂蚁金服SOFARegistry 之 自动调节间隔周期性任务 0x00 摘要 0x01 业务领域 0 ...
- Linux IO/NFS tunning 性能优化及检测
Linux IO/NFS tunning:IO Test=======dd 测试读性能的命令# time dd if=/nfsfolder/testfile of=/dev/null bs=1kdd ...
- python初学者-从小到大排序
x=input("x=") y=input("y=") z=input("z=") if x>y: x,y=y,x if x>z ...
- C# 9 新特性 —— 增强的 foreach
C# 9 新特性 -- 增强的 foreach Intro 在 C# 9 中增强了 foreach 的使用,使得一切对象都有 foreach 的可能 我们来看一段代码,这里我们试图遍历一个 int 类 ...
- 7. JDK拍了拍你:字符串拼接一定记得用MessageFormat#format
目录 ✍前言 版本约定 ✍正文 DateFormat:日期时间格式化 SimpleDateFormat NumberFormat:数字格式化 DecimalFormat 一.0和#的使用(最常见使用场 ...
- Redis基础篇(五)AOF与RDB比较和选择策略
RDB和AOF对比 关于RDB和AOF的优缺点,官网上面也给了比较详细的说明redis.io/topics/pers- RDB 优点: RDB快照是一个压缩过的非常紧凑的文件,保存着某个时间点的数据集 ...
- [leetcode]669. Trim a Binary Search Tree寻找范围内的二叉搜索树
根据BST的特点,如果小于L就判断右子树,如果大于R就判断左子树 递归地建立树 public TreeNode trimBST(TreeNode root, int L, int R) { if (r ...
- 在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
建立测试计划,确定测试标准和测试范围 设计典型场景的测试用例,覆盖常用业务流程和不常用的业务流程等 根据测试用例,开发自动测试脚本和场景: 录制测试脚本:新建一个脚本(Web/HTML协议):点 ...
- Windows Terminal 新手入门
翻译自 Kayla Cinnamon 2020年12月17日的文章<Getting Started with Windows Terminal> [1] 安装 Windows Termin ...