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("")
  • jsp(java server pages)
    • jsp文件内容:直接在原有html代码的基础上,添加java脚本。很方便。

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

  • JSP标签 有2种:

  • JSP指令元素<%@ %>

  • JSP动作元素

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

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

3种java脚本

<% java代码片段 %>



<%=表达式 %>


response.getWriter().print( ... );




<%!声明 成员变量等 %> 

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

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

jsp注释

<%-- 当服务器把jsp编译成java文件前就没有这些注释了! --%> 

案例:演示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的domain用来指定服务器设置的Cookie给哪些域名!当多个二级域中共享Cookie时才需要用
    例如这些二级域名之间需要共享cookie:www.baidu.com、zhidao.baidu.com、news.baidu.com、tieba.baidu.com
    服务器端:
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中添加配置
    unpackWARs="true" autoDeploy="true">

    unpackWARs="true" autoDeploy="true">

  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的最大不活动时间(分钟数)
    
        30
    

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

你可能感兴趣的:(11 - JSP/cookie/HttpSession)