会话、Cookie、Session、url重写

会话

在介绍Cookie与Session之前,想说明一下什么是会话。
会话:可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应。
在JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。
为什么需要会话技术呢?这还地得从Http说起,Http是无状态的,所谓无状态就好像没有记忆一样。要保存一些共享的数据信息,就需要会话技术。

会话跟踪技术:在一个会话的多个请求中共享数据,这就是会话跟踪技术。
四大会话跟踪技术分别是:Cookie,Session,url重写,隐藏域。

Cookie:服务器在一个应答首部传递给浏览器的名称/值对。浏览器保存的时间由cookie的过期时间属性来指定。当浏览器向某个服务器发送一个请求时,它会检查其保存的cookie,并在请求首部中包含从同一台服务器上接收到的所有cookie。
首次都是通过URL传递的,即在URL后跟一个ID标识。然后会判断客户端是否接受cookie,接受的话,存放在cookie里。不接受的话,仍然利用URL传递,即id保存在每次的URL里。

Session :在浏览器和服务器之间不直接传送所有的状态信息,而只是传递表示符(session ID)。浏览器发送sessionID,服务器跟踪与该会话相关联的所有信息。传递sessionID可以通过cookie和URL复写技术,大部分容器都支持这两种技术。服务器无法分辨用户是否关闭了浏览器,因此关闭浏览器意味着与先前的会话关联的所有会话数据都保留在服务器上,直到会话超时,服务器销毁会话对像。

跟踪同一会话中的请求的会话ID可以有多种方法,主要有cookie和url复写。

URL复写:把会话ID编码在URL中。
例:counter.jjsp;jsessionnid=be8d697876787876befdbde898789098980
这样,即使浏览器不支持cookie,也能够实现会话跟踪。
对于URL复写,服务器从请求的URI中提取出会话ID,并把该请求与相应的会话关联起来,然后在访问会话数据的时候,JSP页面所进行的处理方式就和使用cookie跟踪会话id时所使用的方式完全相同。所以sesssion的实现要依靠cookie或URL复写技术。
如果想为不支持cookie的浏览器提供会话跟踪,就必须使用<c:url>行为对应用程序中的所有URL进行复写。这意味着应用程序中的所有页面(至少是那些带有对其他页面引用的页面)都必须是JSP页面,这样页面引用才能以动态方式进行编码,如果遗漏了一个url,那么服务就会失去对会话的跟踪。

隐藏表单域:隐藏表单域是将会话ID添加到HTML的隐藏表单中(类型为hidden的input)。


Cookie

什么是Cookie?
Cookie是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递。用户每次访问站点时,Web应用程序都可以读取Cookie包含的信息。

Cookie的作用: Cookie为Web应用程序保存用户相关信息提供了一种有用的方法。例如,当用户访问您的站点时,您可以利用Cookie保存用户首选项或其他信息,这样,当用户下次再访问您的站点时,应用程序就可以检索以前保存的信息。

Http协议与Cookie

(1) Cookie是HTTP协议制定的!

  • Cookie是HTTP协议制定的,而不是Java Web的,也就是说,在ASP.NET,php等中都可以使用Cookie。
  • 先由服务器保存Cookie到浏览器,再下次浏览器请求服务器时把上一次请求得到Cookie再归还给服务器。

(2) 服务器保存Cookie的响应头
由服务器创建保存到客户端浏览器的一个键值对!服务器保存Cookie的响应头:Set-Cookie: aaa=AAA Set-Cookie: bbb=BBB

(3) 浏览器归还Cookie的请求头
当浏览器请求服务器时,会把该服务器保存的Cookie随请求发送给服务器。浏览器归还Cookie的请求头:Cookie: aaa=AAA; bbb=BBB

Cookie API
javax.servlet.http.Cookie类用于创建一个Cookie,response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法:

  • public Cookie(String name,String value)
  • setValue与getValue方法
  • setMaxAge与getMaxAge方法
  • setPath与getPath方法
  • setDomain与getDomain方法 .google.com
  • getName方法
    上面只有getName()方法,没有setName()方法,说明Cookie的键值对中,键即name,是不能被修改的,需要新的name,就使用Cookie构造方法创建

Cookie设置时间:
(1) Cookie的最大生命,即Cookie可保存的最大时长。
(2) 以秒为单位。
(3) 例如:cookie.setMaxAge(60)表示这个Cookie会被浏览器保存到硬盘上60秒。
(4) maxAge的值。

  • maxAge>0:浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值决定。
  • maxAge<0:Cookie只在浏览器内存中存在,当用户关闭浏览器时,浏览器进程结束,同时Cookie也就死亡了。
  • maxAge=0:浏览器会马上删除这个Cookie!
    设置路径
    (1) Cookie的path并不是设置这个Cookie在客户端的保存路径!!!
    而是设置浏览器将这个Cookie带回给服务器时需要的路径。
    实际上,同一浏览器不同归还路径下的Cookie都是保存在同一个缓存里。
    (2) Cookie的path由服务器创建Cookie时设置。
    (3) 当浏览器访问服务器某个路径时,需要归还哪些Cookie给服务器呢?这由Cookie的path决定。
    (4) 浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会归还这个Cookie。

注意:Cookie不能跨浏览器

Cookie cookie=new Cookie("mycookie", str); //创建Cookie
response.addCookie(cookie); //添加Cookie

//将Cookie信息显示
Cookie cookies[]=request.getCookies(); 
for(int i=0;i< cookies.length;i++){ 
out.print(cookies[i].getName+=+ cookies[i].getValue()); 
} 

Session

HttpSesssion是什么?

  • javax.servlet.http.HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttSession对象中!
  • HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
  • HttpSession是Servlet三大域对象之一(request、session、application(ServletContext)),所以它也有setAttribute()、getAttribute()、removeAttribute()方法
  • HttpSession底层依赖Cookie,或是URL重写!

获取HttpSession对象

  • HttpSession
    request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;

  • HttpSession request.getSession(boolean):当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;
    HttpSession的作用

  • 会话范围
    会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
    会话:一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器!

  • 作用:在会话范围内共享数据
    session域相关方法

  • void setAttribute(String name, Object value);

  • Object getAttribute(String name);

  • void removeAttribute(String name);

HttpSession原理

原理
(1) request.getSession()方法会检查请求中有没有JSESSIONID cookie,如果有拿出他的值找到对应的session为他服务.
(2) 如果没有则检查请求的URL后有没有以参数的形式带着JSESSIONID过来,如果有则找到对应的Session为浏览器服务器
(3) 如果还是找不到,则认为这个浏览器没有对应的Session,创建一个Session然后再在响应中添加JSESSIONID cookie,值就是这个Session 的id
(4) 默认情况下,JSESSIONID 的path为当前web应用的名称,并且没有设置过MaxAge,是一个会话级别的cookie.
(5)这意味着一旦关闭浏览器再新开浏览器时,由于JSESSIONID丢失,会找不到之前的Session
(6) 我们可以手动的发送JSESSIONID cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session

request.getSession()方法

request.getSession()三种形式:

  • request.getSession(false)、request.getSession(true)、request.getSession(),后两个方法效果相同,
  • 第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象。
    获取Cookie中的JSESSIONID
  • 如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
  • 如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
  • 如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了。

返回session

返回sessionID给浏览器

  • 如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在。
  • 请求时通过sessionID找到服务器中的session
    下次请求时,再次执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是同一session对象。
    服务器创建session时间
    服务器不会马上给你创建session,在第一次获取session时,才会创建!request.getSession();

Url重写

为什么要URL重写

  • 如果浏览器禁用了Cookie,浏览器就没有办法JSESSIONID cookie,这样就用不了Session了.
  • 我们可以使用URL重写的机制,在所有的超链接后都以参数的形式拼接
  • JSESSIONID信息,从而在点击超链接时可以使用URL参数的方式获JSESSIONID,从而使用Session

什么是URL重写

将URL进行重写拼接上JSESSIONID的过程就叫做URL重写
创建出Session
request.getSession() --在URL重写之前一定要先创建出Session,才有Session id,才能进行重写
重写方法
response.encodeURL()— 一般的地址都用这个方法重写
response.encodeRedirectURL() — 如果地址是用来进行重定向的则使用这个方法
未禁用Cookie
url重写的方法一旦发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作
案例

productlist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

      <%-- 

      <a href="<%=request.getContextPath() %>/buyServlet?product=电视机">电视机</a>

      <a href="<%=request.getContextPath() %>/buyServlet?product=冰箱">冰箱</a>

      <a href="<%=request.getContextPath() %>/payServlet">结账</a>

     --%>
      <%
        request.getSession();   //Tomcat 9  好像已经不需要这句了 
        String url1=request.getContextPath()+"/buyServlet?product=电视机";
        url1=response.encodeURL(url1);
        String url2=request.getContextPath()+"/buyServlet?product=冰箱";

        url2=response.encodeURL(url2);
        String url3=request.getContextPath()+"/payServlet";
        url3=response.encodeURL(url3);
      %>
      <a href="<%=url1 %>">电视机</a>

      <a href="<%=url2 %>">冰箱</a>

      <a href="<%=url3 %>">结账</a>

      

</body>

</html>

package com.session.basic.servlet;

import java.io.IOException;

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 javax.servlet.http.HttpSession;

@WebServlet("/buyServlet")

public class BuyServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

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

		request.setCharacterEncoding("UTF-8");

		String product=request.getParameter("product");

		//product=new String(product.getBytes("iso8859-1"),"utf-8");

		HttpSession session=request.getSession();

		Cookie cookie=new Cookie("JSESSIONID",session.getId());

		cookie.setMaxAge(1800);//30分钟

		cookie.setPath(request.getContextPath());

		response.addCookie(cookie);

		session.setAttribute("product", product);

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);

	}

}

package com.session.basic.servlet;

import java.io.IOException;

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;

@WebServlet("/payServlet")

public class PayServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

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

		response.setContentType("text/html;charset=utf-8");

		HttpSession session=request.getSession();

		String product=(String)session.getAttribute("product");

		response.getWriter().write("您购买的是:"+product+" 价值10000000元");

		

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);

	}

}

Cookie与Session总结:

Cookie

  • cookie是客户端技术
  • 数据保存在客户端,这个信息可以保存很长时间
  • 数据随时有可能被清空,所以cookie保存的数据是不太靠谱的
  • 数据被保存在了客户端,随时有可能被人看走,如果将一些敏感信息比如用户名密码等信息存在cookie中,可能有安全问题

Session

  • session是服务器端技术
  • 数据保存在服务区端,相对来说比较稳定和安全
  • 占用服务器内存,所以一般存活的时间不会太长,超过超时时间就会被销毁.我们要根据服务器的压力和session的使用情况合理设置session的超时时间,既能保证session的存活时间够用,同时不用的session可以及时销毁减少对服务器内存的占用.
发布了81 篇原创文章 · 获赞 25 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43090158/article/details/103798552