javaWeb核心技术第八篇之Cookie和Session

会话技术:
	    会话是什么?
			浏览器和服务器交互,浏览器打开网页访问服务器,会话开始,正常交互.
			浏览器关闭,会话结束.
		会话能干什么?
			会话可以共享数据.
			Cookie和session将数据保存在不同的位置  进行数据共享
	
	Cookie入门案例
		
		1.创建一个cookie对象
			a. Cookie cookie = new Cookie(String name,String value);
		2.响应给浏览器
			a.Response.addCookie(cookie)
		3.再次请求时需要获得cookie
			a.Request.getCookies() 获得的是数组(包含所有的cookie,如果没有cookie,返回值为null)
		4.Cookie.getName() 获得名称  cookie.getValue() 获得值

	Cookie原理--会话级别cookie
		Http中头信息进行数据传输
		Cookie默认是会话级别的cookie,浏览器打开访问服务器 ,交互的时候数据共享,当前浏览器关闭的时候数据失效.
	
	Cookie细节--持久化级别的cookie
	
		以后开发需要设置时间(cookie的存活时间)
		Cookie.setMaxAge(秒)
		以后开发需要设置路径(访问路径)(作用:cookie 作用域 如果请求地址栏跟cookie文件里cookie路径一致 自动携带)
		Cookie.setPath("/")  (作用:表示该服务器下所有的项目允许共享cookie)
		
		  6)如果不设置cookie的有效存活时间,默认cookie只在内存中有效,当程序结束后,内存中的cookie销毁,不会写入浏览器的缓存中,因此,
		  需要为cookie设置一个有效的时间,当程序运行完毕后,会将该cookie写入浏览器的缓存中,即硬盘中保留。如果cookie的存活时间为0,
		  就相当于浏览器将删除cookie删除或无效.
		  7)在默认情况下,day08web应用的cookie只能被day08web应用的动态资源访问,如果要让其它的web资源访问,得设置cookie.setPath("/day08-2"),默认cookie的path为当前web应用。
		  8)cookie是以文本文件的方式存于浏览器缓存中,而且里面的内容明码.   
		
	cookie细节:(面试)
		1.cookie的value不可以为中文(因为在响应头,响应头在数据传输时,使用是http协议,而协议使用的是iso-8859-1 不支持中文)
		2.cookie的设置 遵循4 2 3规则.
		2.1:4 表示4kb :设置value的是长度是有限的(精准)
		2.2:2 表示20个 : 表示一个网站(站点)最多支持20个cookie(不精准)
		2.3:3 表示300个 : 一个浏览器最大存放cookie是300个(不精准)

案例:记录本次登录时间,显示上次访问时间
	
	//编码
	response.setHeader("content-type","text/html;charset=utf-8");
	
	//2.第二次访问
	//2.1获得请求中携带的cookie数据
	Cookie[] cookies = request.getCookies();
	//2.2判断数据是否为空
	if(cookies != null) {
		for(Cookie cookie : cookies) {
			//判断是最后一次访问的cookie
			if("lasttime".equals(cookie.getName())) {
				response.getWriter().print("您上次访问时间是" + cookie.getValue());
				//重新赋值
				//1.第一次访问
				//1.1创建一个cookie
				Cookie cookie1 = new Cookie("lasttime",new Date().toLocaleString());
				
				//1.1.1 设置最大存活时间
				cookie1.setMaxAge(60*60);
				//1.1.2设置路径
				cookie1.setPath("/");
				
				//1.2将cookie响应给浏览器
				response.addCookie(cookie1);
			}
		}
	}else {
		//1.3打印第一访问
		response.getWriter().print("您是第一次访问服务器");
		//1.第一次访问
		//1.1创建一个cookie
		Cookie cookie = new Cookie("lasttime",new Date().toLocalString());
		
		//1.1.1设置最大存活时间
		cookie.setMaxAge(60*60);
		//1.1.2设置路径
		cookie.setPath("/");
		
		//1.2将cookie响应给浏览器
		response.addCookie(cookie);
	}
	
	Session的底层基于cookie,cookie只用于保存id,服务器根据id去找session对象
	    过程:
		    1.服务器第一次调用getSession()将创建一个Session对象,并且会给这个session对象赋值唯一的id属性sessionld = 1234.
			2.session的底层创建一个cookie对象,目的sessionid传给浏览器 new Cookie(jsessionid,1234),浏览器端会自动保存jsessionid
			3.下一次再次请求时,自动携带jsession=1234,服务器第二次调用getSession()根据session获得唯一的session对象.
			总结:session的底层基于cookie
	
	Session生命周期:
		
		问题:如果浏览器端禁用cookie session能否使用?
			session生命周期
			session的底层基于cookie,使用的是会话级的cookie,浏览器关闭cookie,但session还是存在服务器,只是因为cookie丢了,所以session找不回来了.
			
		创建:
		  1.第一次调用request.getSerssion()时创建.
		销毁:
		  2.1:超时30分钟自动销毁,tomcat配置可以修改(路径在:tomcat -- conf -- web.xml)
		  例如:
		      <session-config>
				<session-timeout>30</session-timeout>
			  </session-config>
		 2.2 手动调用 session.invalidate()销毁.或者setMaxInactiveInterval(int interval)(不常用)
		 2.3 服务器非正常关闭.
			开启服务器后,点击了Console的红色按钮.
		
		session如何持久化?
		    将sessionid保存到数据库或者可以在浏览器端将cookie持久化.
	
	作用域对象总结:
	
		数据共享:Servlet中的域对象.
		类型ServletRequest    HttpSession    ServletContext
		对象request 			session		 ServletContext
		
	api:
	setAttribute(String name,Object value) : 
	getAttribute(String name) 返回值Ojbect : 
	removeAttribute() : 
	
	域对象:在一定范围内共享数据.
	request:一个请求内多个资源可以共享数据(使用的技术 请求转发)
	session:一个会话内共享数据,可以有多个请求.
	servletContext : 一个项目内多个会话,多个请求共享同一份数据(全局变量时使用)
	
	以后作用域如何选择?
	1.能小不大原则.
	2.需求优先原则.
	
	Cookie也可以进行数据共享,但不是域对象,因为指的是服务器端技术.
	Cookie和Session关系?如何选择?
	Session的底层基于cookie.
	如何选择?主要看数据的重要程度.
	
	如果想使用Servlet必须要有tomcat , web中一共13套规范(接口) tomcat支持servlet和jsp
		
	一次性验证码
	
	@WebServlet(urlPatterns={"/BDVerifyCodeServlet"})//等效web.xml配置
public class BDVerifyCodeServlet extends HttpServlet{
	
	 // 图片高度
    private static final int IMG_HEIGHT = 100;
    // 图片宽度
    private static final int IMG_WIDTH = 30;
    // 验证码长度
    private static final int CODE_LEN = 4;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	        // 用于绘制图片,设置图片的长宽和图片类型(RGB)
	        BufferedImage bi = new BufferedImage(IMG_HEIGHT, IMG_WIDTH, BufferedImage.TYPE_INT_RGB);
	        // 获取绘图工具
	        Graphics graphics = bi.getGraphics();
	        graphics.setColor(new Color(100, 230, 200)); // 使用RGB设置背景颜色
	        graphics.fillRect(0, 0, 100, 30); // 填充矩形区域

	        // 验证码中所使用到的字符
	        char[] codeChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456".toCharArray();
	        String captcha = ""; // 存放生成的验证码
	        Random random = new Random();
	        
	        
	        graphics.setFont(new Font("楷体", Font.BOLD, 20));
	        for(int i = 0; i < CODE_LEN; i++) { // 循环将每个验证码字符绘制到图片上
	            int index = random.nextInt(codeChar.length);
	            // 随机生成验证码颜色
	            graphics.setColor(new Color(random.nextInt(150), random.nextInt(200), random.nextInt(255)));
	            // 将一个字符绘制到图片上,并制定位置(设置x,y坐标)
	            graphics.drawString(codeChar[index] + "", (i * 20) + 15, 20);
	            captcha += codeChar[index];
	        }
	        // 将生成的验证码code放入sessoin中
	        req.getSession().setAttribute("code", captcha);
	        // 通过ImageIO将图片输出
	        ImageIO.write(bi, "JPG", resp.getOutputStream());
	    }
}

//效验
try{
	//编码--
	request.setCharacterEncoding("utf-8");
	response.setHeader("content-type","text/html;charset=utf-8");
	
	//1.获得
	//1.1用户输入的验证码 -- 表单的组件需要有name属性
	String verifyCode = request.getParameter("verifyCode");
	//1.2获得图片生成的验证码
	Object code = request.getSession().getAttribute("code");
	//1.3情况session中验证码
	request.getSession().removeAttribute("code");
	if(code == null) {
		//3.1存放错误记录
		request.setAttribute("msg","验证码失效");
		//3.2请求转发给当前页面form.html
		request.getRequestDispatcher("/form.jsp").forward(request,response);
		return ;//等效else
	}

//2.处理 //equalsIgnoreCase  不区分大小写
	if(verifyCode.equalsIgnoreCase(code.toString())) {
		//3.响应成功
		response.getWriter.prinltn("success");
	}else {
		//3.失败 请求转发
		//3.1存放错误记录
		request.setAttribute("msg","验证码错误");
		//3.2请求转发给当前页面form.jsp
		request.getRequestDispatcher("/form.jsp").forward(request,response);//刷新页面
		
	}
	
}catch(Exception e) {
	
}


debug : 里面在Progress窗口下报building和sleeping,那就是编译不过去了.
如果能编译过去,在Project窗口下点击Clean(可以重新编译一个,或者多个),出现Building workspace有绿色条,说明没问题,如果没有
那就是Eclipse挂掉了.解决的办法就是重新启动.
	
案例:
public class Parent {
	public void demo1() {
		System.out.println("1");
		this.demo2();
		//在编译时,this的确表示parent
		//但在运行时,表示是son
	}
	//不可以删,如果删了,编译不过去
	public void demo2() {
		System.out.println("2");
	}
}

public class Son extends Parent {
	public void demo1() {
		super.demo1();
		System.out.println("3");
		this.demo2();
	}
	
	public void demo2() {
		System.out.println("4");
	}
	public static void main(String[] args) {
		Son son = new Son();//new 是谁 this代表谁.
		son.demo1();
	}
	
	答案:1434
}
	
更改项目的jdk版本:项目右键 -- Project Facets -- java -- 1.7(改这里) 和 Java Compiler -- JDK -- 1.7(改这里)
	
JS : 函数问题
	//1.函数的声明问题 跟参数没有关系 只要函数名称一样  产生覆盖的效果
	//2.函数的调用问题 跟参数没有关系
	//3.函数当中有arguments 用来接收所有的数据
 
   function demo2() {
	   alert(1);
   }
   function demo2() {
		alert(arguments.length);//arguments 表示一个数组,用数组来接收传过来的所有参数值
		//arguments.length : 获取的是这个数组的长度
	    alert(a);
	
   }
   demo2("1","2","3");
   
   //$(对象).css("参数") ; 获得 (底层是这么判断的,如果arguments是1表示就一个参数,这样就是表示获得,如果不止一个参数,那就是设置)
   //$(对象).css("参数","参数"); 设置

js中遍历;
    var arr = new Array("三金","三金","丝巾");
	//普通遍历
	for(var i = 0;i < arr.length ; i++) {
		alert(arr[i]);
	}
	//增强遍历(forin)  foreach(Object obj : 数组) :(var相当于Object;variables相当于索引(或者说是key或者是下标); :相当于in ; 数组相当于arr)
	for(var variables in arr) {
		alert(arr[variables]);
	}
   arr["abc"] = "1234";//数组可以使用字符串当下标(数组的属性)
   alert(arr["abc"]);
   </srcipt>
  </head>
  <body>
	<input id="usernameId" type="text" name="username" value="二斤rose" />
	
	<script>
		var userNameObj = document.getElementById("usernameId");
		//增强for  可以遍历对象的属性
		//现在的userNameObj相当于是一个数组
		for(var temp in userNameObj) {
			alert(temp);//temp表示属性的key值(例如:type,name,value等等很多)
			if(temp == "value") {
				//数组名[temp]
				alert(userNameObj[temp]);
			}
		}
	</script>
  </body>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发杂记

Liquibase的简单使用

LiquiBase是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。它的目标是...

20360
来自专栏迈向前端工程师

JS基础测试: 下列等式返回值是true的是?

规范中提到, 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,并且规定null 和 undefined 是相等的。

11940
来自专栏迈向前端工程师

JS基础测试: 下列JS变量定义正确的是​?

变量可以使用短名称(比如 x 和 y),也可以使用描述性更好的名称(比如 age, sum, shuke)。

10820
来自专栏五分钟学算法

算法和编程面试题精选TOP50!(附代码+解题思路+答案)

这份面试资源主要包含五部分内容:数组、链表、字符串、二叉树和重要算法(如排序算法)的编程面试题,其中每部分内容我们都列出了一些最常被问到的热门问题,并且在每个题...

24630
来自专栏java思维导图

为你的IDE集成AI,解放双手,我推荐这款神器!

我们平时写代码的时候,多少都会依赖编辑器的代码补全功能,敲几个字母就能补全一个词。可是这么多年过去了,语言升级了很多次,而代码提示却没有升级,还是只能限定在一个...

63950
来自专栏开发杂记

Java对于表达式中的自动类型提升

8520
来自专栏架构专题

将java进程转移到“解剖台”之前,法医都干了什么?

作为法医,不怕高度腐烂的尸体,也不怕错综复杂的案情。最怕的,是没留下任何东西。空无一物,任何高超的技术,丰富的经验,都无从下手。

10420
来自专栏架构专题

对数字,要有个概念(正好800字)

在刘慈欣的《超新星纪元》中,描述到12辆满载了味精的火车,只够全国人民吃1天;小湖一样大小的汽油,也只够全国烧1天,当时看到也是吃了一惊。而在《编程珠玑》第七章...

8520
来自专栏开发杂记

java web项目中引入spring

Step2:下载spring的jar包http://repo.spring.io/libs-release-local/org/springframework/...

33530
来自专栏java思维导图

万万没想到,JVM内存结构的面试题可以问的这么难?

在我的博客中,之前有很多文章介绍过JVM内存结构,相信很多看多我文章的朋友对这部分知识都有一定的了解了。

8220

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励