03-JavaWeb开发最详细的Cookie&Session分析
Posted ahcfl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03-JavaWeb开发最详细的Cookie&Session分析相关的知识,希望对你有一定的参考价值。
typora-copy-images-to: img
typora-root-url: img
知识回顾
request&http&response&ServletContext
1.request域对象:一次请求和响应使用。
用来存储数据setAttribute(name,value) 获取数据getAttribute(name) 删除数据
2.http响应报文协议:
响应行:状态码 200 OK 302 重定向 404找不到资源 500 服务器异常 304 浏览器缓存
响应头:key:value
refresh ---- 秒数;url=服务器地址
content-type---告知浏览器文件的MIME类型(文件在服务器中的文件类型 text/plain text/html)
location:结合302重定向
content-disposition:告知浏览器以附件下载:“attachment;filename=文件名”
响应体:
getWriter()响应字符数据
getOutputStream()响应字节数据
3.response对象:服务器响应给浏览器数据的对象
1)setStatus(状态码)
2)setHeader(key,value); setContentType("text/html;charset=utf-8");
sendRedirect()重定向
4.ServletContext:域对象,表示整个web项目,并且每个web项目只有一个ServletContext对象,
tomcat启动创建对象,关闭tomcat对象消失。多次请求和响应
Arrays的asList方法【掌握】
注意一:
1.使用数组工具类Arrays中的asList方法将数组转换为集合,因为集合的数据是来自于数组,数组长度固定不变,所以这里要求集合的长度不能改变
2.如果将基本数据类型的数组转换为集合,那么数组类型不能是基本数据类型,必须是包装类类型注意二:
包装类缓冲池 byte 常量池 :
针对byte范围的数据,jvm专门单独开辟一个byte常量池。其实就是一个数组。
查阅源码,针对-128到127之间的数据做了一个数据缓冲池,
如果数据是该范围内的,每次并不创建新的空间。直接从数组中拿数据。反之,需要创建新的空间。例如:Integer的数据直接赋值,如果在-128到127之间,会直接从缓冲池里获取数据
package com.itheima.sh.demo_02;
public class Demo01 {
public static void main(String[] args) {
//包装类面试题
Integer i1 = new Integer(50);
Integer i2 = new Integer(50);
System.out.println(i1 == i2); //false 凡是new的,都走堆内存中创建一块新的空间
Integer i3 = new Integer(500);
Integer i4 = new Integer(500);
System.out.println(i3 == i4); //false
--------------------------------------------------------------------------------
// 发生了自动装箱 ,实现原理:Integer static Integer valueOf(int i)
// 返回一个表示指定的 int 值的 Integer 实例
/*
源码:
class Integer{
//Integer类中的成员内部类
private static class IntegerCache{
static final int low = -128;
static final int high;
static final Integer cache[];
//静态代码块
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
//上述代码调用这个函数创建
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
//i的值在-128和127之间
if (i >= IntegerCache.low && i <= IntegerCache.high){
/*如果i在-128和127之间,则执行这个return语句,将i的值存在
某个数组空间中,下次i的值相同情况下,继续返回相同空间的值*/
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
}
}
*/
解析:
public static Integer valueOf(int i) {
if (i >= -128 && i <= 127)
//传递的值在-128到127直接直接到数组cache中获取内容
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
--------------------------------------------------------------------------------
Integer i5 = 50; //Integer.valueOf(50); -128-127自动装箱
Integer i6 = 50;
System.out.println(i5 == i6); //true 因为i5和i6的值都是50,到静态数组cache获取同一个空间数据
--------------------------------------------------------------------------------
// 针对-128到127之间的数据做了一个数据缓冲池,
// 如果数据是该范围内的,每次并不创建新的空间。直接从数组中拿数据。反之,需要创建新的空间。
//new Integer(i) ---> new Integer(500)
Integer i7 = 500;
//new Integer(i) ---> new Integer(500)
Integer i8 = 500;
System.out.println(i7 == i8);//false
}
}
package com.itheima.sh.c_cookie_test_03;
import java.util.Arrays;
import java.util.List;
/*
注意:
1.使用数组工具类Arrays中的asList方法将数组转换为集合,因为集合的数据是来自于数组,数组长度固定不变,
所以这里要求集合的长度不能改变
2.如果将基本数据类型的数组转换为集合,那么数组类型不能是基本数据类型,必须是包装类类型
*/
public class Demo02 {
public static void main(String[] args) {
method_3();
method_2();
method_1();
}
private static void method_3() {
//1.定义整数数组
// Integer[] arr = {10,20,30}; //自动装箱Integer.valueOf(10) -128-127byte常量池 new Integer();
Integer[] arr = {Integer.valueOf(10),Integer.valueOf(20),Integer.valueOf(30)};
//2.转化为集合
// public static <T> List<T> asList(T... a) {}
List<Integer> list = Arrays.asList(arr);
System.out.println(list.size()); //3
System.out.println(list); //{10,20,30}
}
private static void method_2() {
//1.定义整数数组
int[] arr = {10,20,30};
//2.转化为集合
// public static <T> List<T> asList(T... a) {}
List<int[]> list = Arrays.asList(arr);
System.out.println(list.size()); //1
System.out.println(list); //[[I@1540e19d]
}
private static void method_1() {
//1.创建数组
String[] arr = {"abc","def","abc"};
//2.将上述数组转换为List集合
List<String> list = Arrays.asList(arr);
//给list集合添加数据
// list.add("哈哈"); //Exception in thread "main" java.lang.UnsupportedOperationException
// list.remove("def"); //Exception in thread "main" java.lang.UnsupportedOperationException
//获取
// System.out.println(list.get(0));
//修改元素内容不是集合长度
list.set(0, "呵呵");
//3.输出集合数据
System.out.println("list = " + list);
}
}
一、Cookie技术
1、什么是会话【掌握】
用户打开浏览器访问网站开始直到关闭浏览器的过程就是一次会话。
2、Cookie介绍
Cookie属于一个类,可以直接创建对象
Cookie是在服务器端创建,保存在浏览器端
tomcat服务器将创建的cookie以及cookie中的数据响应给浏览器,
当使用HttpServletResponse中的对象调用方法addCookie将服务器创建的cookie直接保存到浏览器端
当我们下次访问同一个服务器会携带相同的cookie信息,在服务器中我们可以使用HttpServletRequest对象调用方法getCookies获取随着请求携带过来的所有的cookie。
好处:减轻服务器压力
弊端:不安全
3、Cookie的应用场景
【1】购物车 : 例如现在的苏宁易购,不登录账户也可浏览商品,并添加购物车。
【2】记住用户名和密码:例如 b站 用户登陆页面,勾选框,浏览器可记住用户名和密码。
说明:目前还不能完成第二次访问登录页面,在页面中取出cookie中的用户名和密码。
4、Cookie的常用API(重要)
【1】需求:上述应用场景中我们目前还不能完成第二次访问登录页面,在页面中取出cookie中的用户名和密码。我们可以实现第二次访问服务器取出cookie中的数据。
【2】图解
方法 | 使用示例 | 说明 |
---|---|---|
创建Cookie对象 | Cookie(String name,String value)name表示指定 cookie 名称 ,value 表示指定 cookie 值 | Cookie c1 = new Cookie(“username”,“suoge”) |
获取cookie的name值 | String getName() | c1.getName() |
获取cookie的value值 | String getValue() | c1.getValue() |
设置cookie的值 | void setValue(String value) | c1.setValue(“李四”) |
【3】构造方法
Cookie(String name, String value)
【4】操作Cookie类中的name和value方法
1.String getName() // 获取cookie类中的name值
2.String getValue() // 获取cookie类中的value值
3.void setValue(String newValue) // 修改value值
【5】使用HttpServletResponse中的对象调用方法addCookie将服务器创建的cookie直接保存到浏览器端
void addCookie(Cookie cookie) 参数需要一个cookie类的对象
【6】使用HttpServletRequest对象调用方法getCookies获取随着请求携带过来的所有的cookie。
Cookie[] getCookies() 获取随着请求的所有cookie放到数组中
【7】案例实现
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/loginServlet" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
记住用户名和密码:<input type="checkbox" name="check"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
loginServlet:
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.处理post请求乱码
request.setCharacterEncoding("utf-8");
//2.获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//3.获取复选框的value属性值
String check = request.getParameter("check");
//4.判断用户是否希望记住用户名和密码
if("on".equals(check)){
//5.假设用户希望记住,我们创建cookie对象将用户名和密码存储到cookie中
//Cookie(String name, String value)
Cookie cookie1 = new Cookie("username", username);
Cookie cookie2 = new Cookie("password", password);
//6.响应给浏览器 void addCookie(Cookie cookie) 参数需要一个cookie类的对象
response.addCookie(cookie1);
response.addCookie(cookie2);
}
}
}
login02Servlet:
@WebServlet("/login02Servlet")
public class Login2Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取页面中所有的cookie 使用HttpServletRequest对象调用方法getCookies获取随着请求携带过来的所有的cookie。
//Cookie[] getCookies() 获取随着请求的所有cookie放到数组中
Cookie[] cookies = request.getCookies();
//2.遍历数组取出用户名和密码的cookie
for (Cookie cookie : cookies) {
//3.输出用户名和密码的cookie中的value值和name值
String cookieName = cookie.getName();
//判断是否是用户名
if("username".equals(cookieName)){
System.out.println(cookieName+"----"+cookie.getValue());
}else if("password".equals(cookieName)){
//判断是否是密码
System.out.println(cookieName+"----"+cookie.getValue());
}
}
}
}
5、关于cookie中存储特殊字符问题 (理解原理)
如果直接向cookie中存储特殊字符,例如空格,分号(😉,逗号(,),等号(=)等特殊字符。那么就会出现问题。
在向cookie中存储特殊字符之前必须要先进行编码处理,然后从cookie中取出之后在进行解码处理。
1、cookie中不能直接存储特殊字符:空格 分号等,如果存储必须先编码在存储:
String encode = URLEncoder.encode(str, "utf-8");
2、在获取的时候需要解码:
String decode = URLDecoder.decode(value, "utf-8");
【1】向cookie中存储特殊字符问题演示
@WebServlet("/specialCookie01Servlet")
public class SpecialCookie01Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
向cookie中存储特殊字符问题演示
*/
//1.创建Cookie类的对象
Cookie cookie = new Cookie("msg", "12 34");
//2.将cookie存储到浏览器端
response.addCookie(cookie);
}
}
【2】解决向cookie中存储特殊字符的问题
方案:在向cookie中存储特殊字符前进行编码,然后取出之后需要解码。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
向cookie中存储特殊字符问题演示
*/
//1.创建Cookie类的对象
// Cookie cookie = new Cookie("msg", "12 34");报错
String str = "12 34";
//编码
String encode = URLEncoder.encode(str, "utf-8");
Cookie cookie = new Cookie("msg", encode);
//2.将cookie存储到浏览器端
response.addCookie(cookie);
}
}
@WebServlet("/specialCookie02Servlet")
public class SpecialCookie02Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取浏览器的cookie
Cookie[] cookies = request.getCookies();
//2.遍历cookie数组
for (Cookie cookie : cookies) {
//3.取出cookie的name
String cookieName = cookie.getName();
//4.判断cookieName的值是否是msg
if("msg".equals(cookieName)){
//5.取出value
String value = cookie.getValue();
//6.解码并输出
String decode = URLDecoder.decode(value, "utf-8");
System.out.println(decode);
}
}
}
}
6、Cookie的存活时间setMaxAge() 【重要】
【1】需求:向cookie中存储数据,并设置cookie的存活时间为1周;
cookie默认的存活时间是会话结束即关闭浏览器。
我们平常开发中对于某些cookie中存储的数据希望保存的时间更长一些,而不是浏览器关闭就不存在。
如果想让cookie长久保存我们可以使用Cookie类的方法即可
cookie分为两种
>1)会话级别的cookie:关闭浏览器cookie自动销毁
>
>2)**持久化级别的cookie**:**通过Cookie类的方法setMaxAge设置cookie的存活时间**
void setMaxAge(int expiry) 参数是秒
@WebServlet("/cookiePersis01Servlet")
public class CookiePersis01Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected 史上最详细解释接口自动化测试中cookiesession和token的区别多测师