cookie与session

Cookie

简介

Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据。

 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来。

 当客户端再次请求同一服务器时,客户端会在请求头中添加该服务器保存的Cookie,发送给服务器。

Cookie规范
Cookie通过请求头和响应头在服务器与客户端之间传输;
 Cookie大小限制在4KB之内;
一台服务器在一个客户端最多保存20个Cookie;
一个浏览器最多可以保存300个Cookie;
虽然Cookie规范是如此,但在今天,浏览器厂商的竞争异常激烈,所以多少会超出Cookie规则的限制。但也不会超出过多!

cookie的使用

我们有两种设置cookie的方法,1 通过响应头来设置cookie  2 通过response.addcookies() 方法便捷设置cookie。

让我们来看看使用代码:

public class AServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.addHeader("set-cookie","name=123");//通过设置响应头来设置cookie
		response.addHeader("set-cookie", "password=123456");
		Cookie c = new Cookie("aihao" , "nv");//我们先new一个cookie对象
		Cookie d = new Cookie("xingqu" , "nv");
		response.addCookie(c);//将我们new 的cookie对象添加上去
		response.addCookie(d);
	}
}

//服务器端获取cookie
public class BServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setHeader("Content-Type", "text/html;charset=utf-8");
		PrintWriter pw =response.getWriter();
		Cookie[] cs = request.getCookies();
		for(Cookie e : cs) {
			pw.write(e.getName() + "=" + e.getValue() + "<br/>");
		}
		pw.close();
		
	}

}


cookie的其他方法

1 设置其最大存活时间 Cookie的maxAge

当服务器创建Cookie对象后,可以调用setMaxAge()方法设置Cookie的最大生命。
  maxAge > 0:表示Cookie在客户端硬盘上保存的最大时间,单位为秒;
  maxAge < 0:表示Cookie不会被浏览器保存到硬盘上,而只在浏览器内存中存活,一旦客户端关闭浏览器在,那么Cookie就消失;
  maxAge == 0:表示删除Cookie,例如客户端硬盘已经存在名为abc的Cookie,如果服务器再向客户端发送名为abc,并且maxAge为0的Cookie,那么表示删除客户端上的名为abc的Cookie。

2 设置其path路径

注意其path路径并不是你想的那样哦,当你设置了cookie的path路径后,当你访问的url路径包含在cookie的path路径中是,浏览器就会发送该cookie给服务器对象。

如果没有设置path路径,那么它的path默认为当前Servlet的所在路径。

我们了看看他的使用代码:

j's'p<%@page import="java.net.URLEncoder"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'jsp1.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
  <!-- 相当于java代码中的方法体内部 -->
  <h1>添加cookie</h1>
    <% 
    	/* cookie不能保存中文所以使用中文是就必须得进行url编码 */
    	String name = URLEncoder.encode("魏金浩", "utf-8");
    	String value = URLEncoder.encode("呵呵哒", "utf-8");
    	Cookie c = new Cookie(name , value);
    	c.setMaxAge(-1);
    	c.setPath("/day_11/jsp/jsp1.jsp");/* 当我们这是了"/day_11/jsp1.jsp"path路径,我们在请求jsp2.jsp中浏览器就不会返回这个cookie了 */
   		response.addCookie(c); 
    %>
    
  </body>
</html>
<%@page import="java.net.URLDecoder"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'jsp2.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <h1>得到COOKIE</h1>
    <%
    	String d = null;
    	String e = null;
    	Cookie[] c = request.getCookies();
    	if(c != null) {
	    	for(Cookie s : c) {
	    		
	    		String name = URLDecoder.decode(s.getName(),"utf-8");/* 进行解码 */
	    		if("魏金浩".equals(name)) {
	    			 d = name;
	    			 String value = URLDecoder.decode(s.getValue(),"utf-8");/* 进行解码 */
	    			 e = value;
	    		}
	    	}
    	}
    %>
    cookie: <%=d %>=<%=e %>
  </body>
</html>

应为cookie是不允许传递中文的,这里面还涉及到了如何传递中文的方法,大家可以参考一下。

好了,cookie的内容咱们就说到这把,让我们在来研究一下session对象吧。

HttpSession

简介

HttpSession可和http协议无关了,这是我们的三大域对象之一(request,session,application),session域对象的域自然就是这个会话的过程了。我想这个不难理解吧。

也就是说服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。

常用方法

既然是域对象自然少不了这三个方法了:

session.setAttribute();
session.getAttribute();
session.removeAttribute();
这三个方法我们已近玩烂了,我就不细说了。

那摩我们如何得到session对象呢?

request.getSession();//得到session对象

好了,我们即能得到session了,也能设置属性了,他的大部分工作已经完成了,但是为了我们更好的使用session对象来实现数据的共享,我们有必要了解一下他的原理。

session原理

 1.session是依赖Cookie实现的。


  2.session是服务器端对象


  3.当用户第一次使用session时(表示第一次请求服务器),服务器会创建session,并创建一个Cookie,在Cookie中保存了session的id,发送给客户端。这样客户端就有了自己session的id了。但这个Cookie只在浏览器内存中存在,也就是说,在关闭浏览器窗口后,Cookie就会丢失,也就丢失了sessionId。


  4.当用户第二次访问服务器时,会在请求中把保存了sessionId的Cookie发送给服务器,服务器通过sessionId查找session对象,然后给使用。也就是说,只要浏览器容器不关闭,无论访问服务器多少次,使用的都是同一个session对象。这样也就可以让多个请求共享同一个session了。


  5.当用户关闭了浏览器窗口后,再打开浏览器访问服务器,这时请求中没有了sessionId,那么服务器会创建一个session,再把sessionId通过Cookie保存到浏览器中,也是一个新的会话开始了。原来的session会因为长时间无法访问而失效。


  6.当用户打开某个服务器页面长时间没动作时,这样session会超时失效,当用户再有活动时,服务器通过用户提供的sessionId已经找不到session对象了,那么服务器还是会创建一个新的session对象,再把新的sessionId保存到客户端。这也是一个新的会话开始了。

哦了,再多我也就不说了,要不然你们就嫌我啰嗦了,让我们来看一个应用吧!

演示登录功能:


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'log.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
<!--   当浏览器禁用了cookie时我们可以使用url重写的方法达到同样的效果 -->
<!-- response.encodeURL("/day_11/LogServlet");当客户端禁用cookie时会自动生成带JSESSIONID参数的的url路径即:/day_11/LogServlet;JSESSIONID=********
当没有禁用是会返回原值 -->
  <body>
  <form action=<%=response.encodeURL("/day_11/LogServlet") %> method="post">
	  <h1 align="center">登陆</h1>
	  <table align="center">
	   	<tr>
	   		<td>用户名:</td>
	   		<td><input type="text" name="username"></td>
	   	</tr>
	   	<tr>
	   		<td>密码:</td>
	   		<td><input type="password" name="password"></td>
	   	</tr>
	   	<tr>
	   		<td><input type="submit" value="登陆"></td>
	   		<td><input type="submit" value="注册"></td>
	   	</tr>
	   </table>
   </form>
  </body>
</html>

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'success.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <%
    	HttpSession s = request.getSession();
   	    String username = (String)s.getAttribute("username");
   	    if(username == null) {
   	    	response.sendRedirect(response.encodeURL("/day_11/LogServlet"));
   	    }
    %>
    hello <%=username %>
  </body>
</html>

package sessiontest;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LogServlet extends HttpServlet {

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		if("weijinhao".equals(username)) {
			if("123456".equals(password)) {
				HttpSession s = request.getSession();
				s.setAttribute("username",username);
				response.setStatus(302);
				response.setHeader("location", response.encodeURL("/day_11/session/success.jsp"));
			}
			else {
				response.setStatus(302);
				response.setHeader("location", response.encodeURL("/day_11/session/log.jsp"));
			}
		}
		else {
			response.setStatus(302);
			response.setHeader("location", response.encodeURL("/day_11/session/log.jsp"));
		}
	}

}

乍一看代码挺多但其实大部分都是不用看的,就看最主要的就行了,你懂的。

我估计大家会问我为什么提交表单和重定向是使用response.encodeURL();呢我们来讲解一下:

URL重写
 session依赖Cookie,这是因为服务器需要把sessionId保存到客户端。如果用户的浏览器关闭了Cookie功能,那么session不能使用了!
 还可以在浏览器关闭了Cookie后使用URL重写的方法保存sessionId,这需要在每个URL后面都加上sessionId!这样用户的请求中就包含了sessionId,服务器就可以通过sessionId找到对应的session对象了。
  使用response.encodeURL()方法对URL进行编码,这样URL中会智能的添加sessionId。
 当浏览器支持cookie时,response.encodeURL()方法不会在URL后追加sessionId
  当浏览器不支持cookie时,response.encodeURL()方法会在URL后追加sessionId


session的API:


 String getId():获取sessionId;


 nt getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;


 void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;


long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;


long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;


void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;


 boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

最后还得说一下:


session与浏览器


 session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
 因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。也就是说,使用IE登录后,再使用FireFox访问服务器还是没有登录的状态。
 而且同时打开多个相同浏览器的窗口,是在使用同一session。如果你使用的是老浏览器,例如IE6,那么就会每个窗口一个session。

哦了,我们就聊到这里,我要去睡觉了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值