jsp简介

JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,是一种动态网页技术标准。它是在传统的网页HTML文件中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。

它实现了Html语法中的java扩展(以 <%, %>形式)。JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。

jsp优缺点与servlet的关系

jsp优缺点

优点:在原有html的基础上添加java脚本,构成jsp页面。
缺点:html标签中包含大量的java代码,不利于后期的维护。

jsp与servlet关系

jsp的本质就是一个servlet,所有servlet 可以做的事情,jsp 都可以做。但是两者各有优缺点。
jsp擅长的是页面的展示,包括发起界面(form表单),结束界面(显示数据table),可以直接使用html标签,而不需要使用大量的需要大量的response.getWriter().print(““)。
Serlvet:用来处理数据
jsp:显示数据
jsp当中的所有的内容,实际上都是会被转换成 out.writer()…

jsp页面的组成部分

jsp页面的组成主要包含以下部分:

  1. - html标签
  2. - 注释(htmljsp注释)
  3. - jsp动作标签
  4. - 指令
  5. - 小脚本<% %>
  6. - 表达式<%= %>
  7. - 申明<%! %>

html标签

支持所有的html标签。也可以直接使用(css/js)。就像写html页面一样写jsp页面

注释

jsp页面中可以使用两种注释。

    • html注释:<!—html注释 —>:在页面源码中是可以看见的
    • jsp注释:<%—jsp注释—%>:在页面源码中是隐藏的,只能看源代码查看。

jsp内置动作标签

jsp内置的标签库,不同的标签拥有不同的功能
jsp常用的动作标签有:参考http://www.runoob.com/jsp/jsp-actions.html

jsp指令

jsp指令用来设置整个JSP页面相关的属性,指令可以有很多个属性,它们以键值对的形式存在,并用逗号隔开。
jsp中的三种指令标签:

指令 描述
<%@ page … %> 指定页码的属性,例如设置编码格式
<%@ include … %> 静态包含,可以用来包含其他文件
<%@ taglib … %> 引入标签库的定义,可以引入第三方标签库(jstl)

page指令

page指令用来指定页面的属性,例如:如下设置jsp使用的脚本语言及文档类型

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

下表列出与Page指令相关的属性:

属性 描述
buffer 指定out对象使用缓冲区的大小
autoFlush 控制out对象的 缓存区
contentType 指定当前JSP页面的MIME类型和字符编码
errorPage 指定当JSP页面发生异常时需要转向的错误处理页面
isErrorPage 指定当前页面是否可以作为另一个JSP页面的错误处理页面
extends 指定servlet从哪一个类继承
import 导入要使用的Java类
info 定义JSP页面的描述信息
isThreadSafe 指定对JSP页面的访问是否为线程安全
language 定义JSP页面所用的脚本语言,默认是Java
session 指定JSP页面是否使用session
isELIgnored 指定是否执行EL表达式
isScriptingEnabled 确定脚本元素能否被使用


jsp脚本

JSP脚本就是Java代码片段,它分为三种:

  • <%…%>:小脚本,Java语句;
  • <%=…%>:Java表达式;
  • <%!…%>:申明,Java定义类成员;

小脚本

  1. <body>
  2. <%
  3. String text = "hello 你好";
  4. System.out.println(text);
  5. %>
  6. </body>

表达式

  1. <body>
  2. <%
  3. String text = "hello 你好";
  4. System.out.println(text);
  5. %>
  6. <%=text %>
  7. </body>

申明

  1. <body>
  2. <!--定义一个方法-->
  3. <%!public String sayHello() {
  4. return "hello";
  5. }%>
  6. <%=sayHello()%>
  7. </body>

jsp案例

  • 用户登录,注册。
  • 当用户登录成功之后跳转到主界面显示所有的员工信息。

用户登录实现思路

  • a.创建jsp页面,登录。
  • b.创建LoginServlet接收登录的请求,处理验证。
  • c.创建jdbc连接数据库。
  • d.如果验证成功,跳转到主页面。

jsp内置对象

在JSP中无需创建就可以使用的9个对象,它们是:

  • out(JspWriter):等同与response.getWriter(),用来向客户端发送文本数据;
  • config(ServletConfig):对应“真身”中的ServletConfig;
  • page(当前JSP的真身类型):当前JSP页面的“this”,即当前对象;
  • pageContext(PageContext):页面上下文对象,它是最后一个没讲的域对象;
  • exception(Throwable):只有在错误页面中可以使用这个对象;
  • request(HttpServletRequest):即HttpServletRequest类的对象;
  • response(HttpServletResponse):即HttpServletResponse类的对象;
  • application(ServletContext):即ServletContext类的对象;
  • session(HttpSession):即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<%@page session=”false”%>,说明这个页面不能使用session。

EL表达式语言

EL的作用

JSP2.0要把html和css分离、要把html和javascript分离、要把Java脚本替换成标签。标签的好处是非Java人员都可以使用。
JSP2.0 –纯标签页面,即:不包含<% … %>、<%! … %>,以及<%= … %>
EL(Expression Language)是一门表达式语言,它对应<%=…%>。我们知道在JSP中,表达式会被输出,所以EL表达式也会被输出。
主要作用用来替换jsp当中<%= %>语句

EL的格式

  1. 格式:${…}
  2. 例如:${price}*${number} ==${price*number}
  3. 表达式:1+2;
  4. 语句:int a= 1+2;

关闭EL

如果希望整个JSP忽略EL表达式,需要在page指令中指定isELIgnored=”true”。 默认是true。
如果希望忽略某个EL表达式,可以在EL表达式之前添加“\”,例如:${1 + 2}。

EL运算符

运算符 说明 范例 结果
+ ${17+5} 22
- ${17-5} 12
* ${17*5} 85
/或div ${17/5}或${17 div 5} 3
%或mod 取余 ${17%5}或${17 mod 5} 2
==或eq 等于 ${5==5}或${5 eq 5} true
!=或ne 不等于 ${5!=5}或${5 ne 5} false
<或lt 小于 ${3<5}或${3 lt 5} true
>或gt 大于 ${3>5}或${3 gt 5} false
<=或le 小于等于 ${3<=5}或${3 le 5} true
>=或ge 大于等于 ${3>=5}或${3 ge 5} false
&&或and 并且 ${true&&false}或${true and false} false
!或not ${!true}或${not true} false
||或or 或者 ${true||false}或${true or false} true
empty 是否 为空 ${empty “”},可以判断字符串、数据、集合的长度是否为0,为0返回true。empty还可以与not或!一起使用。${not empty “”} true

EL不显示null

当EL表达式的值为null时,会在页面上显示空白,即什么都不显示。

JSTL标签库

  • JSTL(JavaServer Pages Standard Tag Library,JSP标准标签库)
  • JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是JSP内置的标签,需要我们自己导包,以及指定标签库而已!
  • 如果你使用MyEclipse开发JavaWeb,那么在把项目发布到Tomcat时,你会发现,MyEclipse会在lib目录下存放jstl的Jar包!如果你没有使用MyEclipse开发那么需要自己来导入这个JSTL的Jar包:jstl-1.2.jar。

JSTL标签库

JSTL一共包含四大标签库:

  • core:核心标签库,我们学习的重点,也称为C标签;
  • fmt:格式化标签库,只需要学习两个标签即可;
  • sql:数据库标签库,不需要学习了,它过时了;
  • xml:xml标签库,不需要学习了,它过时了。

image.png

使用taglib指令导入标签库

除了JSP动作标签外,使用其他第三方的标签库都需要:

  • 导包

    1. <dependency>
    2. <groupId>javax.servlet</groupId>
    3. <artifactId>jstl</artifactId>
    4. <version>1.2</version>
    5. </dependency>
  • 在使用标签的JSP页面中使用taglib指令导入标签库;

下面是导入JSTL的core标签库:

  1. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • prefix=”c”:指定标签库的前缀,这个前缀可以随便给值,但大家都会在使用core标签库时指定前缀为c;
  • uri=”http://java.sun.com/jstl/core“:指定标签库的uri,它不一定是真实存在的网址,但它可以让JSP找到标签库的描述文件;

core标签库常用标签

out

输出aaa字符串常量
与${aaa}相同
当${aaa}不存在时,输出xxx字符串

if

  1. if标签的test属性必须是一个boolean类型的值,如果test的值为true,那么执行if标签的内容,否则不执行。
  1. <c:set var="a" value="hello"/>
  2. <c:if test="${not empty a }">
  3. <c:out value="${a }"/>
  4. </c:if>

choose

choose标签对应Java中的if/else if/else结构。when标签的test为true时,会执行这个when的内容。当所有when标签的test都为false时,才会执行otherwise标签的内容。

  1. <!--选择标签 if else if else -->
  2. <c:choose>
  3. <c:when test="${map.age<18}">
  4. <c:out value="未成年"></c:out>
  5. </c:when>
  6. <c:when test="${map.age>=18 && map.age < 30}">
  7. <c:out value="青年人"></c:out>
  8. </c:when>
  9. <c:when test="${map.age>=30 && map.age < 60}">
  10. <c:out value="中年人"></c:out>
  11. </c:when>
  12. <c:otherwise>
  13. </c:otherwise>
  14. </c:choose>

forEach

forEach当然就是循环标签了,forEach标签有两种使用方式:

  • 使用循环变量,指定开始和结束值,类似for(int i = 1; i <= 10; i++) {};
  • 循环遍历集合,类似for(Object o : 集合);

遍历集合或数组方式:
  1. <c:forEach var="score" items="${socreArray}">
  2. <c:out value="${score}"></c:out>
  3. </c:forEach> <br/>

遍历List
  1. <c:forEach var="data" items="${list}">
  2. <c:out value="${data.name}"></c:out> <br/>
  3. </c:forEach> <br/>

遍历Map
  1. <c:forEach var="map" items="${data}">
  2. <c:out value="key = ${map.key} value = ${map.value} "></c:out> <br/
  3. </c:forEach>

varStatus

  1. forEach标签还有一个属性:varStatus,这个属性用来指定接收“循环状态”的变量名,例如:<forEach varStatus=”vs …/>,这时就可以使用vs这个变量来获取循环的状态了
  • count:int类型,当前以遍历元素的个数;
  • index:int类型,当前元素的下标;从0开始
  • first:boolean类型,是否为第一个元素;
  • last:boolean类型,是否为最后一个元素;
  • current:Object类型,表示当前项目。 ```xml

    1. <c:if test="${vs.first}">
    2. <c:out value="${map.name} 是第一条记录"></c:out>
    3. </c:if> <br/>
    4. <c:if test="${vs.last}">
    5. <c:out value="${map.name} 是最后一条记录"></c:out>
    6. </c:if> <br/>
  1. <c:if test="${vs.index == 2}">
  2. <c:out value="${map.name} 是第三条"></c:out>
  3. </c:if>
  4. </c:forEach>
  1. <a name="ER9nk"></a>
  2. ### fmt标签库常用标签
  3. fmt标签库是用来格式化输出的,通常需要格式化的有时间和数字。
  4. **格式化时间:**
  5. ```xml
  6. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  7. ......
  8. <%
  9. Date date = new Date();
  10. pageContext.setAttribute("d", date);
  11. %>
  12. <fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss"/>

格式化数字:

  1. <%
  2. double d1 = 3.5;
  3. double d2 = 4.4;
  4. pageContext.setAttribute("d1", d1);
  5. pageContext.setAttribute("d2", d2);
  6. %>
  7. <fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
  8. <fmt:formatNumber value="${d2 }" pattern="#.##"/>

会话跟踪技术

什么是会话跟踪技术

http协议 是一个无状态协议:每次请求都是独立的,第一次请求和第二次请求没有关系的

我们需要先了解一下什么是会话(多次请求)!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应。例如你给10086打个电话,你就是客户端,而10086服务人员就是服务器了。从双方接通电话那一刻起,会话就开始了,到某一方挂断电话表示会话结束。在通话过程中,你会向10086发出多个请求,那么这多个请求都在一个会话中。

在JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。


在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:

  1. - 请求银行主页;
  2. - 请求登录(请求参数是用户名和密码);
  3. - 请求转账(请求参数与转账相关的数据);
  4. - 请求信用卡还款(请求参数与还款相关的数据)。

在这上会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

什么是会话呢?我 们可以通俗一点理解。只要你的browers(浏览器)不关闭我们就称这一系列的request与response为一个会话。一断你close就称这个会话已结束。 虽然会话结束但并不代表你的session就被destroy.因为session是存活在server上的。它的生命完全由server来主宰 (tomcat服务器web.xml中的设定)
虽然你的session还存活在server上但你已无法再取得它。因为j2ee的api只给我们一种方法来取得与当前会话相关的session的引用:request.getsession() or reqeust.getsession(boolean)

会话跟踪技术

会话跟踪技术使用Cookie或session完成

我们知道HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪!
在JavaWeb中,使用session来完成会话跟踪,session底层依赖Cookie技术。

常见的cookie场景

  • 记住用户名和密码(不安全)
  • 商品浏览记录
  • 猜你喜欢
  • 购物车

Cookie

什么叫Cookie

浏览器与WEB服务器之间是使用HTTP协议进行通信的,当某个用户发出页面请求时,WEB服务器只是简单的进行响应,然后就关闭与该用户的连接。因此当一个请求发送到WEB服务器时,无论其是否是第一次来访,服务器都会把它当作第一次来对待,这样的不好之处可想而知。为了弥补这个缺陷,Netscape开发出了cookie这个有效的工具来保存某个用户的识别信息,因此人们昵称为“小甜饼”。

image.png

Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

Cookie规范

  • Cookie大小上限为4KB;
  • 一个服务器最多在客户端浏览器上保存20个Cookie;
  • 一个浏览器最多保存300个Cookie;

上面的数据只是HTTP的Cookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等但也不会出现把你硬盘占满的可能!

cookie属于客户端
注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。

Cookie第一例

我们这个案例是,客户端访问AServlet,AServlet在响应中添加Cookie,浏览器会自动保存Cookie。然后客户端访问BServlet,这时浏览器会自动在请求中带上Cookie,BServlet获取请求中的Cookie打印出来。

image.png

AServlet.java

  1. /**
  2. * 给客户端发送Cookie
  3. * @author Administrator
  4. *
  5. */
  6. public class AServlet extends HttpServlet {
  7. public void doGet(HttpServletRequest request, HttpServletResponse response)
  8. throws ServletException, IOException {
  9. response.setContentType("text/html;charset=utf-8");
  10. String id = UUID.randomUUID().toString();//生成一个随机字符串
  11. Cookie cookie = new Cookie("id", id);//创建Cookie对象,指定名字和值
  12. response.addCookie(cookie);//在响应中添加Cookie对象
  13. response.getWriter().print("已经给你发送了ID");
  14. }
  15. }

BServlet.java

  1. /**
  2. * 获取客户端请求中的Cookie
  3. * @author Administrator
  4. *
  5. */
  6. public class BServlet extends HttpServlet {
  7. public void doGet(HttpServletRequest request, HttpServletResponse response)
  8. throws ServletException, IOException {
  9. response.setContentType("text/html;charset=utf-8");
  10. Cookie[] cs = request.getCookies();//获取请求中的Cookie
  11. if(cs != null) {//如果请求中存在Cookie
  12. for(Cookie c : cs) {//遍历所有Cookie
  13. if(c.getName().equals("id")) {//获取Cookie名字,如果Cookie名字是id
  14. response.getWriter().print("您的ID是:" + c.getValue());//打印Cookie值
  15. }
  16. }
  17. }
  18. }
  19. }

Cookie的生命

什么是Cookie的生命

Cookie不只是有name和value,Cookie还是生命。所谓生命就是Cookie在客户端的有效时间,可以通过setMaxAge(int)来设置Cookie的有效时间。

cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。

cookie.setMaxAge(60*60):表示cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时;

cookie.setMaxAge(0):cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端盘上都会删除这个Cookie。

浏览器查看cookie

在google浏览器中输入:

  1. chrome://settings/siteData

浏览器—>设置—>高级—->内容设置—->Cookie—->查看所有 Cookie 和网站数据

案例:显示上次访问时间

创建Cookie,名为lasttime,值为当前时间,添加到response中;
在AServlet中获取请求中名为lasttime的Cookie;
如果不存在输出“您是第一次访问本站”,如果存在输出“您上一次访问本站的时间是xxx”;

Cookie中保存中文

Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。

向客户端响应中添加Cookie

  1. String name = URLEncoder.encode("姓名", "UTF-8");
  2. String value = URLEncoder.encode("张三", "UTF-8");
  3. Cookie c = new Cookie(name, value);
  4. c.setMaxAge(3600);
  5. response.addCookie(c);



从客户端请求中获取Cookie

  1. response.setContentType("text/html;charset=utf-8");
  2. Cookie[] cs = request.getCookies();
  3. if(cs != null) {
  4. for(Cookie c : cs) {
  5. String name = URLDecoder.decode(c.getName(), "UTF-8");
  6. String value = URLDecoder.decode(c.getValue(), "UTF-8");
  7. String s = name + ": " + value + "<br/>";
  8. response.getWriter().print(s);
  9. }
  10. }

弊端:

  • 保存在客户端,安全性差;
  • 无法实现多浏览器,多电脑之间的数据共享

优点

  • 不需要占用服务器资源。

HttpSession概述

什么是HttpSesssion

javax.servlet.http.HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到 HttpSession对象中。
会话:就是一系列的请求。session是实现会话跟踪技术的一种,另一种可以使用cookie实现。
http是属于一种无状态的协议(一次请求完之后,所有的都消失了)。
session的底层依赖与cookie。

获取HttpSession对象


  • HttpSession request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;
  • HttpSession request.getSession(boolean):当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;

HttpSession是域对象

我们已经学习过HttpServletRequest、ServletContext,它们都是域对象,现在我们又学习了一个HttpSession,它也是域对象。它们三个是Servlet中可以使用的域对象,而JSP中可以多使用一个域对象

  • HttpServletRequest:一个请求创建一个request对象,所以在同一个请求中可以共享request,例如一个请求从AServlet转发到BServlet,那么AServlet和BServlet可以共享request域中的数据;
  • ServletContext:一个应用只创建一个ServletContext对象,所以在ServletContext中的数据可以在整个应用中共享,只要不启动服务器,那么ServletContext中的数据就可以共享;
  • HttpSession:一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享session中的数据;

session的域方法:

  • void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:session.setAttribute(“xxx”, “XXX”),在session中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;
  • Object getAttribute(String name):用来获取session中的数据,当前在获取之前需要先去存储才行,例如:String value = (String) session.getAttribute(“xxx”);,获取名为xxx的域属性;
  • void removeAttribute(String name):用来移除HttpSession中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;
  • Enumeration getAttributeNames():获取所有域属性的名称;

session其他常用API

  1. //获取sessionId
  2. String getId();
  3. //获取session可以的最大不活动时间(秒),默认为30分钟。
  4. //当session在30分钟 内没有使用,那么Tomcat会在session池中移除这个session;
  5. int getMaxInactiveInterval();
  6. //设置session允许的最大不活动时间(秒),
  7. //如果设置为1秒,那 么只要session在1秒内不被使用,那么session就会被移除;
  8. void setMaxInactiveInterval(int interval);
  9. //返回session的创建时间,返回值为当前时间的毫秒值
  10. long getCreationTime();
  11. //返回session的最后活动时间,返回值为当前时间的毫秒值
  12. long getLastAccessedTime();
  13. //(退出登录)让session失效!调用这个方法会被session失效,当session失效后,
  14. //客户端再次请求,服务 器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
  15. void invalidate();
  16. //查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,
  17. //但这时服务器还 没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
  18. boolean isNew();


淘宝……吃饭(30分钟)….买买(登录失效,重新登录)

session的实现原理

session底层是依赖Cookie的!我们来理解一下session的原理吧!

当我首次去银行时,因为还没有账号,所以需要开一个账号,我获得的是银行卡,而银行这边的数据库中留下了我的账号,我的钱是保存在银行的账号中,而我带走的是我的卡号。

当我再次去银行时,只需要带上我的卡,而无需再次开一个账号了。只要带上我的卡,那么我在银行操作的一定是我的账号!

当首次使用session时,服务器端要创建session,session是保存在服务器端,而给客户端的session的id(一个cookie中保存了sessionId)。客户端带走的是sessionId,而数据是保存在session中。

当客户端再次访问服务器时,在请求中会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session。

服务器是如何实现一个session为一个用户浏览器服务的?

服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。可以用如下的代码证明:

image.png

第一次访问

image.png

第二次访问

image.png

session与浏览器

session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命是-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。

当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId中到Cookie中发送给客户端。 

你可能会说,那原来的session对象会怎样?当一个session长时间没人使用的话,服务器会把session删除了!这个时长在Tomcat中配置是30分钟,可以在${CATALANA}/conf/web.xml找到这个配置,当然你也可以在自己的web.xml中覆盖这个配置!

web.xml

  1. <session-config>
  2. <session-timeout>30</session-timeout>
  3. </session-config>

session失效时间也说明一个问题!如果你打开网站的一个页面开始长时间不动,超出了30分钟后,再去点击链接或提交表单时你会发现,你的session已经丢失了!

Session和Cookie主要区别

  • Cookie是把用户的数据写给用户的浏览器。好处不占用服务器资源,安全性低
  • Session技术把用户的数据写到用户独占的session中。
  • Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。