1.Cookie
1.Cookie概述
会话:浏览器和服务器之间的多次请求和响应
会话过程中所产生的一些数据,可以通过会话技术(Cookie和Session)保存
Cookie:客户端会话管理技术
把要共享的数据保存到客户端(浏览器)
每次请求时,把会话信息带到服务器端,从而实现多次请求的数据共享
作用:可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率
2.Cookie常见属性
属性名称 | 属性作用 | 是否重要 |
---|---|---|
name | cookie的名称 | 必要属性 |
value | cookie的值(不能是中文) | 必要属性 |
path | cookie的路径 | 重要 |
domain | cookie的域名 | 重要 |
maxAge | cookie的生存时间 | 重要 |
version | cookie的版本号 | 不重要 |
comment | cookie的说明 | 不重要 |
注:
当删除Cookie时,设置maxAge值为0。当不设置maxAge时,使用的是浏览器的内存,当关闭浏览器之后,cookie将丢失。设置了此值,就会保存成缓存文件(值必须是大于0的,以秒为单位)
3.Cookie的方法和添加获取
方法名 | 作用 |
---|---|
Cookie(String name,String value) | 构造方法创建对象 |
属性对应的set和get方法 | 赋值和获取值 |
添加:HttpServletResponse对象中提供了addCookie()方法
返回值 | 方法名 | 作用 |
---|---|---|
void | addCookie(Cookie cookie) | 向客户端添加Cookie |
获取:HttpServletRequest对象中提供了getCookies()方法
返回值 | 方法名 | 作用 |
---|---|---|
Cookie[ ] | getCookies() | 获取所有的Cookie |
因为,cookie是通过服务器端代码将数据保存在浏览器,所以服务器让浏览器做一件事情,肯定是通过响应
而在浏览器存储的数据,要想告诉服务器都有什么,那肯定是通过请求
4.Cookie的使用
需求说明:
通过Cookie记录最后访问的时间并在浏览器上显示出来
最终目的:
掌握Cookie的基本使用,从创建到添加客户端,再从服务器端获取
实现步骤:
1.通过响应对象写出一个提示信息
2.创建Cookie对象,指定name和value
3.设置Cookie最大存活时间
4.通过响应对象将Cookie对象添加到客户端
5.通过请求对象获取Cookie对象
6.将Cookie对象中的访问时间写出
package 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 {
//1.通过响应对象写出提示信息
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.write("欢迎访问本网站,您的最后访问时间为:<br>" );
//2.创建Cookie对象,用于记录最后访问时间
Cookie cookie = new Cookie("time",System.currentTimeMillis()+"");
//3.设置最大存活时间
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);
}
}
5.Cookie的使用细节
数量限制
每个网站最多只能有 20 个 Cookie,且大小不能超过 4KB。所有网站的 Cookie 总数不能超过 300 个
名称限制
Cookie 的名称只能包含 ASCCI 码表中的字母、数字字符。不能包含逗号、分号、空格,不能以 $ 开头
Cookie 的值不支持中文
存活时间限制 setMaxAge() 方法接收数字
负整数:当前会话有效,浏览器关闭则清除
0:立即清除
正整数:以秒为单位设置存活时间
访问路径限制
默认路径:取自第一次访问的资源路径前缀。只要以这个路径开头就能访问到
设置路径:setPath() 方法设置指定路径
访问路径限制案例
@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);
}
}
@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);
}
}
@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);
}
}
@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);
}
}
ServletDemo03、ServletDemo04可以访问到zhangsan,ServletDemo05访问不到zhangsan
结论:Cookie的路径限制
取自第一次访问的资源路径前缀
只要以这个前缀为开头(包括子级路径)就可以获取到
反之获取不到
2.Session
1.session概述
HttpSession:服务器端会话管理技术
本质也是采用客户端会话管理技术
只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中
每次请求时,会将特殊标识带到服务器端,根据这个标识来找到对应的内存空间,从而实现数据共享
是 Servlet 规范中四大域对象之一的会话域对象
作用:可以实现数据共享
域对象 | 功能 | 作用 |
---|---|---|
ServletContext | 应用域 | 在整个应用之间实现数据共享 |
ServletRequest | 请求域 | 在当前的请求或请求转发之间实现数据共享 |
HttpSession | 会话域 | 在当前会话范围之间实现数据共享 |
HttpSession,它虽然是服务端会话管理技术的对象,但它本质仍是一个Cookie
是一个由服务器自动创建的特殊的Cookie,Cookie的名称就是JSESSIONID,Cookie的值是服务器分配的一个唯一的标识
当我们使用HttpSession时,浏览器在没有禁用Cookie的情况下,都会把这个Cookie带到服务器端,然后根据唯一标识去查找对应的HttpSession对象,找到了就可以直接使用了
2.Session的常用方法与获取
常用方法
返回值 | 方法名 | 说明 |
---|---|---|
void | setAttribute(String name,Object) | 设置共享数据 |
Object | getAttribute(String name) | 获取共享数据 |
void | removeAttribute(String name) | 移除共享数据 |
String | getId() | 获取唯一标识名称 |
void | Invalidate() | 让session立即失效 |
获取HttpSession是通过HttpServletRequest接口中的两个方法获取的
返回值 | 方法名 | 说明 |
---|---|---|
HttpSession | getSession() | 获取HttpSession对象 |
HttpSession | getSession(boolean create) | 获取HttpSession对象,未获取到是否自动创建 |
3.Session的使用
package 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);
}
}
@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是否是同一个对象
访问:分别访问两个demo,发现一致(也可以通过Network查看)
4.Session的使用细节
浏览器禁用cookie
方式一:通过提示信息告知用户,大部分网站采用的解决方式(推荐)
package 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(false);
System.out.println(session);
if(session == null){
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("为了不影响正常使用请不要禁用浏览器的Cookie");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
方式二:访问时拼接jsessionid标识,通过encodeURL()方法重写地址
package 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.获取请求的用户名
String username = req.getParameter("username");
//2.获取HttpSession对象
HttpSession session = req.getSession(false);
System.out.println(session);
System.out.println(session.getId());
//3.将用户信息添加到共享数据中
session.setAttribute("username",username);
//实现url重写 相当于在地址栏后面拼接了一个jsessionid
resp.getWriter().write("<a href='"+resp.encodeURL("http://localhost:8080/Session/servletDemo03")+"'>go servletDemo03</a>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
HttpSession的钝化和活化
什么是钝化和活化
钝化:序列化。把长时间不用,但还不到过期时间的 HttpSession 进行序列化,写到磁盘上
活化:相反的状态
何时钝化
第一种情况:当访问量很大时,服务器会根据 getLastAccessTime 来进行排序,对长时间不用,但是还没到过期时间的 HttpSession 进行序列化。
第二种情况:当服务器进行重启的时候,为了保持客户 HttpSession 中的数据,也要对其进行序列化
注意
HttpSession 的序列化由服务器自动完成,我们无需关心
3.JSP
1.JSP概述
JSP(Java Server Pages):是一种动态网页技术标准
动态资源:会变化的数据
动态效果:例如界面上的一些特效,弹框
JSP 部署在服务器上,可以处理客户端发送的请求,并根据请求内容动态的生成 HTML、XML 或其他格式文档的 Web 网页,然后再响应给客户端
JSP 是基于 Java 语言的,它的本质就是 Servlet
类别 | 使用场景 |
---|---|
HTML | 开发静态资源,无法添加动态资源 |
CSS | 美化页面 |
JavaScript | 给网页添加一些动态效果 |
Servlet | 编写java代码,实现后台功能处理 |
JSP | 包含了显示页面技术,也具备java代码功能 |
2.JSP快速入门
1.创建一个web项目
2.在web目录下创建一个index.jsp文件
3.在文件中写一句内容为:这是我的第一个jsp
4.部署并启动项目
5.通过浏览器测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP</title>
</head>
<body>
<h1>这是我的第一个jsp</h1>
</body>
</html>
JSP执行过程
3.JSP语法
1.JSP注释
<%-- 注释的内容 --%>
2. java代码块
<% Java代码 %>
3.JSP表达式
<%=表达式%>
4.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中的声明(变量或方法)
如果加! 代表的是声明的是成员变量
如果不加! 代表的是声明的是局部变量
--%>
<%! String s = "abc";%>
<% String s = "def";%>
<%=s%>
<%! public void getSum(){}%>
<%--<% public void getSum2(){}%> 这个是局部方法,相当于是在getSum里再声明方法,所以不允许--%>
</body>
</html>
4.JSP指令
page指令
语法:<%@ page 属性名=属性值 属性名=属性值 … %>
属性名 | 作用 |
---|---|
contentType | 响应正文支持的类型和设置编码格式 |
language | 使用的语言,默认是 java |
errorPage | 当前页面出现异常后跳转的页面 |
isErrorPage | 是否抓住异常,如果为 true 则页面中就可以使用异常对象,默认是 false |
import | 导包 import=“java.util.ArrayList” |
session | 是否创建 HttpSession 对象,默认为 true |
buffer | 设定 JspWrite 输出 jsp 内容缓存的大小,默认为 8KB |
pageEncoding | 翻译 jsp 是所使用的编码格式 |
isElgnored | 是否忽略 EL表达式,默认是 false |
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”%>
Alt+/ 自动导入
contentType:告知引擎,响应正文的MIME类型。contentType=“text/html;charset=UTF-8”
相当于response.setContentType(“text/html;charset=UTF-8”);
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>
taglib指令
该指令用于引入外部标签库,html标签和jsp标签不用引入
语法格式:<%taglib uri="" prefix=""%>
属性:
uri:外部标签的URI地址
prefix:使用标签时的前缀
tag:标签,lib:library库,prefix:前缀
九大隐式对象
它指的是在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 | 页面域对象 |
PageContext对象
是 JSP 独有的,Servlet 中没有
是四大域对象之一的页面域对象,还可以操作其他三个域对象中的属性(应用域,会话域,请求域)
还可以获取其他八个隐式对象
生命周期是随着 JSP 的创建而存在,随着 JSP 的结束而消失。每个 JSP 页面都有一个 PageContext对象
常用方法查询API
四大域对象
域对象名称 | 范围 | 级别 | 备注 |
---|---|---|---|
PageContext | 页面范围 | 最小,只能在当前页面用 | 因范围太小,开发中用的很少 |
ServletRequest | 请求范围 | 一次请求或当期请求转发用 | 当请求转发之后,再次转发时请求域丢失 |
HttpSession | 会话范围 | 多次请求数据共享时使用 | 多次请求共享数据,但不同的客户端不能共享 |
ServletContext | 应用范围 | 最大,整个应用都可以使用 | 尽量少用,如果对数据有修改需要做同步处理 |
5.MVC模型介绍
M(Model):模型。用于封装数据,封装的是数据模型
V(View):视图。用于显示数据,动态资源用 JSP 页面,静态资源用 HTML 页面
C(Controller):控制器。用于处理请求和响应,例如 Servlet