11 - JSP/cookie/HttpSession

本文目录:

  1. JSP基础
  2. Cookie
  3. HttpSession

JSP基础

JSP(Java Server Pages)是JavaWeb服务器端的动态资源。它与html页面的作用是相同的,显示数据和获取数据。

jsp和Servlet的常见分工

(jsp) request -- servlet -- (jsp) response

  • JSP
    • 作为请求发起页面,把来自用户的post/get等请求发送给servlet:例如页面内含有表单、超链接
    • 作为请求结束页面,接受servlet的数据,显示给用户。
  • Servlet
    • 获取jsp发送来的请求参数
    • 处理请求,得到处理后的数据
    • 把结果保存到request中
    • 转发到显示结果的JSP

jsp的作用

  • Servlet
    • 优点:动态资源(html静态页面不能包含动态信息)
    • 缺点:不适合设置html代码,需要大量的response.getWriter().print("<html>")
  • jsp(java server pages)
    • jsp文件内容:直接在原有html代码的基础上,添加java脚本。很方便。

jsp的组成 jsp = html + java脚本 + jsp标签(指令)

  • JSP标签 有2种:

  • JSP指令元素<%@ %>

  • JSP动作元素<jsp: />

  • jsp的9大内置对象(无需创建即可使用的对象):

    • request
    • response
    • out
    • session
    • application 和tomcat进程“共生死”
    • pageContext
    • config
    • page
    • exception

3种java脚本

<% java代码片段 %>
<!--,常用
可写0到n条Java语句
方法内能写什么,它就可以写什么
-->


<%=表达式 %>

<!--java表达式,用于输出一条表达式(或变量)的结果。-->
response.getWriter().print( ... );
<!--这里能放什么,它就可以放什么!
比如某个具有返回值的函数 func1()
-->



<%!声明 成员变量等 %> 
<!--声明,用来创建类的成员变量和成员方法(基本不用,但容易被考到)
类体中可以放什么,它就可以放什么!

Class man{
成员变量
成员方法
构造器
构造代码块
静态块
内部类
}

-->

out.print()和out.write() 几乎没有区别:

String s = null;
out.print(s); // outputs the text "null"  处理空指针异常,输出字符串“null”。
out.write(s); // NullPointerException  不处理该异常。

jsp注释

<%-- 当服务器把jsp编译成java文件前就没有这些注释了! --%> 
<!--  html注释会发到客户端浏览器。 -->

案例:演示jsp中java脚本的使用!
案例:演示jsp与servlet分工!

jsp原理(理解)

  • 当jsp页面第一次被访问时:
    • 1.服务器会把jsp编译成java文件(这个java其实是一个servlet类)
    • 2.再把java编译成.class
    • 3.创建该类对象
    • 4.最后调用它的service()方法
  • 第二次请求某jsp时,直接调用service()方法。
jsp实质是一种特殊的Servlet

tomcat/work/Catalina目录下可以找到 jsp 对应的 .java 源代码,和生成的.class文件。

  • 查看jsp对应java文件:
  • .java语句,方法体的最上面,声明了9大内置对象,赋值。
  • 原封不动的把程序员写的代码放到方法体下面。
  • html语句,全是这样输出的:out.wirte("字符串");

Cookie

Http协议与Cookie
  • Cookie是HTTP协议制定的!
    服务器保存Cookie到浏览器,再下次浏览器请求服务器时,会带上Cookie
  • 由服务器创建保存到客户端浏览器的一个键值对!”key=value“

服务器保存Cookie的响应头
Set-Cookie: aaa=AAA Set-Cookie: bbb=BBB

response.addHeader("Set-Cookie", "aaa=AAA");
response.addHeader("Set-Cookie", "bbb=BBB");
  • 当客户端浏览器发送request给服务器时,会带上Cookie:
Cookie: aaa=AAA; bbb=BBB
  • Http协议规定(很多浏览器都会在一定范围内违反HTTP规定)
    • 1个Cookie最大4KB
    • 1个服务器最多向1个浏览器保存20个Cookie
    • 1个浏览器最多可以保存300个Cookie
Cookie的用途

注意Cookie不跨浏览器!

  • 跟踪客户端状态
  • 保存购物车信息
  • 只保存上次的登录名,方便登录。
JavaWeb中使用Cookie
  • 原始方式(了解)
  • 使用response发送Set-Cookie响应头
  • 使用request获取Cookie请求头
  • 便捷方式(重要!)
repsonse.addCookie()//让浏览器端保存Cookie

request.getCookies()//获取浏览器端带来的Cookie
//如果HTTP请求没有带来cookie则返回null

服务器端发送response给客户端浏览器,http响应包头中有Set-Cookie头,格式如下:

Set-Cookie: key1=value2
Set-Cookie: key1=value2
Set-Cookie: key1=value2

客户端发送request给服务器时,http请求包头里面有Cookie头,格式如下:

Cookie: key1=value1; key2=value2; key3=value3
Cookie详解
  • Cookie不只有name和value两个属性
  • Cookie的maxAge
    • maxAge>0:Cookie的最大生命。浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值,以秒为单位。cookie.setMaxAge(60)
    • maxAge<0:Cookie只在浏览器内存中存在(浏览器进程结束,Cookie消失)
    • maxAge=0:立即删除同名cookie
  • Cookie的path
    • Cookie的path决定:当浏览器访问服务器某个路径时,带上哪些Cookie
    • Cookie的path不可能是设置这个Cookie在客户端的保存路径!
    • Cookie的path由响应包response创建Cookie时设置
    • 浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会带上这个Cookie。

例如:服务器端设置

aCookie.path=/day11_1/; 
bCookie.path=/day11_1/aaa/; 
cCookie.path=/day11_1/aaa/bbb/;

客户端浏览器
访问:域名/day11_1/anyname.jsp 时带上aCookie
访问:域名/day11_1/aaa/anyname.jsp 时带上aCookie、bCookie
访问:域名/day11_1/aaa/bbb/anyname.jsp 时带上aCookie、bCookie、cCookie

  • Cookie的path默认值:当前访问路径的父路径。
    如访问/day11_1/jsps/a.jsp时响应包设置了cookie,该cookie的默认path为/day11_1/jsps/
cookie.setDomain(".baidu.com");//设置domain  直接省略掉二级域名的不同之处
cookie.setPath("/");//设置path
  • 自己测试,步骤:
  1. 修改本机hosts文件
    127.0.0.1 111.x.com
    123.0.0.1 222.x.com

  2. 在${CATALINA_HOME}/conf/server.xml中添加配置
    <Host name="news.qdmmy6.com" appBase="news"
    unpackWARs="true" autoDeploy="true">
    </Host>
    <Host name="tieba.qdmmy6.com" appBase="tieba"
    unpackWARs="true" autoDeploy="true">
    </Host>

  3. 把tieba和news两个目录copy到${CATALINA_HOME}下

  4. 访问http://news.qdmmy6.com/SaveServlet

  5. 访问http://tieba.qdmmy6.com/GetServlet

Cookie保存中文

Cookie的name和value都是不能直接保存中文的,但可以把中文转换成URL编码后保存到Cookie(name和value中)

  String name = "姓名";
  String value = "张三";
  name = URLEncoder.encode(name, "utf-8");
  value = URLEncoder.encode(value, "utf-8");

  Cookie c = new Cookie(name, value);
  response.addCookie(c);

  //获取Cookie:使用URL解码即可。
  Cookie[] cs = request.getCookies();
  if(cs != null) {
    for(Cookie c : cs) {
      String name = URLDecoder.decode(c.getName(), "utf-8");
      String value = URLDecoder.decode(c.getValue(), "utf-8");
      System.out.println(name + "=" + value);
    }
  }

HttpSession(重点)

HttpSession概述
  • HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!

  • HttpSession底层依赖CookieURL重写

  • HttpSession是Servlet三大域对象之一

  • 三大域对象

  • request

    • 每一次请求都会创建一个request
    • 请求链共享数据 可把request发给多个Servlet
  • session

    • 会话是同一个用户在浏览器打开后关闭前对服务器的多次请求。
  • application(ServletContext)

    • 程序存在,保存在这里的内容就一直存在

三大域对象都有方法:

void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);

session是域对象,所以有setAttribute()和getAttribute()等方法
服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。

会话 会话追踪
  • 会话:同一个用户在浏览器打开后关闭前对服务器的多次请求。
  • 会话范围:某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
  • 会话方便了服务器端共享数据!对客户端浏览器只在Cookie里只有一个session的ID,服务器端在这个session中设置的一些值对用户均不可见。
  • 会话跟踪技术:在一次会话中共享数据。
    HTTP是无状态协议,每个请求之间无法共享数据。这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。这说明需要使用额外的手段来跟踪会话!
  • session缓存:服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存!
  • Servlet中得到session对象HttpSession session = request.getSession();

  • Jsp中得到session对象
    session是jsp内置对象,不用创建,直接使用!如
    <%session.setAttribute("aa","bb")%>

案例1:session 多次请求中共享数据
  • AServlet:向session域中保存数据
  • BServlet:从session域中获取数据
  • 演示:

    第一个请求:访问AServlet
    第二个请求:访问BServlet

案例2:session 保存用户登录信息(精通)
  • 案例相关页面和Servlet:

    • login.jsp:登录页面
    • succ1.jsp:只有登录成功才能访问的页面
    • succ2.jsp:只有登录成功才能访问的页面
    • LoginServlet:校验用户是否登录成功!
  • 各页面和Servlet内容:

    • login.jsp:提供登录表单,提交表单请求LoginServlet
    • LoginServlet:获取请求参数,校验用户是否登录成功
      • 失败:保存错误信息到request域,转发到login.jsp(login.jsp显示request域中的错误信息)
      • 成功:保存用户信息到session域中,重定向到succ1.jsp页面,显示session域中的用户信息
    • succ1.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息
    • succ2.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息

    只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就一起存在!那么用户访问succ1和succ2就会通过!

HttpSession原理(理解)

  • request.getSession()方法

    • 获取Cookie中的JSESSIONID(唯一标识)
    • 如果Cookie中没有sessionId,从url参数中获取 格式为;JsessionID=也没有时,服务器创建一个session并保存,把新创建的sessionId设置到浏览器Cookie中,这个Cookie的生命为-1,即只在浏览器内存中存在!
    • 关闭浏览器前,再次请求,服务器端执行request.getSession()方法,通过客户端带Cookie的请求,得到Cookie中的sessionId,服务器的session对象与上一次请求使用的是同一session对象。
    • 如果sessionId存在,但通过sessionId没有找到session对象(可能超时被服务器删除了),创建session保存到服务器,把新创建的sessionId保存到客户端浏览器的Cookie中
    • 如果sessionId存在,通过sessionId查找到了session对象(不会再创建新session对象)
  • 服务器不会马上给用户创建session,在第一次获取session时才会创建该用户的session!

session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。

//以下都是Servlet的代码:
//所有Servlet如果不写这一行,都不会自动创建session(不会给客户端Set-Cookie)
request.getSession();//如果是服务器端第一次获取Session 则向客户端设置Set-Cookie 
request.getSession(false)//如果请求包的cookie带了JsessionID,则获取;如果没带来sessionid则返回null 且不创建session对象!
request.getSession(true)//有session则得到session,没有则用Set-cookie设置到浏览器
request.getSession()//和上一个方法效果相同

任何JSP页面,都会自动创建session!

HttpSession其他方法

  • String getId()
    • 获取sessionId
  • void invalidate()
    • 调用这个方法会使session让当前session失效!当session失效后,客户端再次请求,服务器会给客户端创建一个新的session在响应中给客户端Set-Cookie 新sessionId
  • boolean isNew()
    • 查看session是否为“New”。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端(还没有发送响应包Set-Cookie:sessionId),此时session的状态为“New”
  • long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
  • long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
  • int getMaxInactiveInterval()
    • 获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
  • void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
request.getSession().isNew();

web.xml中配置session的最大不活动时间(分钟数)
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

URL重写(理解)

HttpSession底层依赖CookieURL重写

session依赖Cookie,目的是让客户端发出请求时带上Cookie(含有sessionId),服务器才能找到对应的session
如果浏览器禁用所有cookie,所以服务器给浏览器Set-Cookie多少遍都没用。只能用URL重写:
让网站的所有超链接(get)、表单(post)中都添加一个名为JSESSIONID的参数,这样服务器通过获取请求参数也能得到sessionId,从而找到session对象。

URL重写,简单说实质:就是把所有的页面中的路径,都使用这条语句处理一下:
response.encodeURL(String url)

该方法会对url进行智能的重写:
当浏览器不支持cookie或支持Cookie但第一次请求时,request中的Cookie没有带sessionid,则response.encodeURL()方法会在URL后追加sessionId(比如首次访问JSP页面)
当request中的Cookie带sessionid时,response.encodeURL()方法不会在URL后追加sessionId

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容