1 JSP的4个作用域
1.2 session作用域
Session作用域中的对象时session对象。
API
Session.setAttribute(String attrName,Object attrValue);
Session.getAttribute(String atrrName);
Session.removeAttribute(String attrName);
Session到底是多大?
一次回话范围:从session的创建到session的失效。
Session的创建时间:第一次访问使用session,就会创建session。
Session的失效:浏览器缓存清空或者超过最大的存活时间。
Session对象在JSP页面中是可以直接使用,因为是内置对象,但是在servlet中需要获取。
获取session的方法:
request.getSession();
获取session,如果当前session存在就直接返回当前的session对象。如果不存在就创建一个session返回。
request.getSession(true/false);
当参数为true和上面的方法解释一致。
当参数为false时,就是如果当前的session是存在就返回当前的session,如果不存在就返回null。
案例:
在session没有失效(关闭浏览器/session过期)的情况下,直接访问first.jsp,second.jsp,secondServlet等等。都可以直接从session中取出设置好的属性。
1.3 application作用域
application作用域中的对象是application对象。
API
application.setAttribute(String attrName,Object attrValue);
application.getAttribute(String atrrName);
application.removeAttribute(String attrName);
application范围是整个应用程序。
从服务器启动到服务器关闭,只有一个application对象存在。所有的请求,所有的回话都使用同一个application对象。使用application对象记录网站的访问数量。
案例:
2 重定向和转发
重定向和转发都是从当前的业务进入另外一个url。
重定向:
response.sendRedirect("second.jsp");
重定向向服务器发送了两次请求。
访问second servlet
最终地址栏显示:
地址栏中显示的是第二次请求的URL
转发:
RequestDispatcher dispatcher = request.getRequestDispatcher("first.jsp");
dispatcher.forward(request, response);
转发:客户端请求了一次。在服务器内部进行自动转发。
访问firstServlet
地址栏中显示的是第一次请求的url,但是页面展示的是最终响应的页面。
通过上面的分析得出结论:重定向中的服务器端的资源(servlet和jsp)是分别在各自的请求范围内的。Request中的数据是不能共享。 转发的资源是同一个请求范围内,所以他们的request的属性数据是共享。
注意观察代码就发现:重定向的时候是不需要传递request和response参数的。转发的时候是需要传入request和response对象的。
转发只能转发到自己的引用中的资源,重定向可以定位到其他应用中的url
当需要将servlet的数据设置到request中传递到jsp的时候,必须使用转发进入jsp。
WEB-INF和META-INF两个文件夹下的所有的资源是不能直接访问的,也就是无法重定向进入其中。但是可以转发进入这两个目录。
3 会话跟踪技术
3.1概述
HTTP是无状态:
HTTP无状态协议,是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
由于HTTP协议不记录访问状态,带来了一些问题,所以产生了会话跟踪技术。这里要使用的就是session和cookie。 当cookie禁用时可能还要使用url重写。
当然更高级的项目,分布式项目在很多情况下都是将session分离的,不使用传统的session进行会话跟踪。
会话跟踪的目标就是,保持客户端的访问状态。记录客户端多次请求的信息。比如:在线购物时,需要登录。无法在下订单的时候获取用户的登录信息。因为登录和下订单是在两次请求中。这里就要用到session,在登录时将用户的登录状态存储到session中。然后下订单时再从session中取出登录状态。
3.2 会话跟踪中的session
Session是会话跟踪技术的核心。Session本身就是表示一次回话,可以在多次请求中共享数据。
服务器端是如何做到多次访问中使用同一个session的。
依靠的就是cookie保存sessionId。
Session如何创建不再赘述。
Session消亡的两种情况也不再赘述。
Session的存活时间
Session的默认存活时间是30分钟, 我们可以通过session的API调整session的存活时间。
案例:记录一次回话中的访问次数
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session HttpSession session = request.getSession(); //设置session的存活时间 session.setMaxInactiveInterval(10); int count = 0; try { count = Integer.parseInt(session.getAttribute("count").toString()); } catch (Exception e) { } count++; session.setAttribute("count", count); System.out.println("回话:"+session.getId()); System.out.println("访问次数:"+count); } |
通过session的API手动清空session
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取session HttpSession session = request.getSession(); //让session失效 session.invalidate(); } |
3.3使用会话跟踪实现登录
[1]修改登录功能
修改servlet,登录成功之后将登录用户信息存储到session中。
[2]修改index页面,在页面显示欢迎信息
未登录状态:
登录状态:
[3]添加一个退出系统的servlet
在此案例中,用户登录成功后,我们将用户对象信息存储在session中,在其他的资源中如果需要使用用户信息,就可以直接从session中获取。
但是要切记切记切记:session是存储在服务器端的,而且不能即时消亡。所以不要在session存储过多的数据。
3.4会话跟踪中的cookie
[1]概述
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265 [1] 。(可以叫做浏览器缓存)
Cookie是服务器端在客户端存储数据的一种手段。
观察浏览器中的cookie。谷歌浏览器:设置,高级,内容设置,cookie
存储在缓存中的cookie
[2]在服务器端创建和发送cookie
Cookie类似于一个键值对。
Tips:cookie的name 和value都是String类型的。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建Cookie对象 Cookie cookie = new Cookie("igeek", "igeekhome"); //将cookie发送到客户端 response.addCookie(cookie); //重定向进入index.jsp response.sendRedirect("index.jsp"); } |
观察结果:
我们的cookie是存储在浏览的缓存中的。
[3]在服务器端获取浏览器携带的cookie
当我们再次访问服务器的时候,浏览器会携带cookie访问。
我们可以在服务器中取出浏览器携带的cookie数据。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过request获取cookie Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { System.out.println(cookie.getName()+":"+cookie.getValue()); } response.getWriter().append("Served at: ").append(request.getContextPath()); } |
当再次访问getCookieServlet时获取到了浏览器携带的cookie
[4]cookie的存活时间
每个cookie都是有存活时间的。默认情况下cookie的存活时间是会话结束。
默认情况下,cookie是存储在缓存中。
可以通过cookie的setMaxAge设置cookie的存活时间。
如果设置为0就是删除cookie。(有的浏览器不支持此操作,一般的做法是将age设置为0,将value设置为””)。
如果是大于0的一个整数,cookie就会存储在磁盘上。一旦存储在磁盘上,即使会话结束cookie也不会消失。
设置cookie存活时间:
浏览器中的cookie就会存储到磁盘中:
关闭浏览器,再打开cookie依然存在:
通过修改cookie的存活时间删除cookie.
创建DeleteCookieServlet,添加删除cookie的程序:
先访问CookieServlet。会创建cookie igeek,再访问deleteCookie会删除cookie。
Tips:将cookie的存活时间设置为 “-1”时,cookie会从持久化状态(存储在磁盘上)修改为存储在缓存中(浏览器回话结束就消亡)。
[5]cookie中的路径
Cookie在没有设置路径的情况下,默认路径就是当前访问的url所在路径
比如:
标记为红框的就是访问产生的cookie的路径
案例:
添加CooiePahtServlet url:
访问:
Cookie的路径:
通过getCookie的servlet获取所有的cookie
访问:
发现在servlet获取不到 cookie cpath。
因为cookie在不同的路径下是不共享。
比如:
在url: manager/user/save 添加一个cookie。
在url: manager/product/*** 获取不到上面设置的cookie。浏览不会携带上面设置的cookie过来。
在url: manger/user/save 添加用cookie 。
可以访问的路径如下:
manger/user/xxxx
manger/user/xxx/xxx
当然也可以通过cookie的setPath设置cookie的路径:
浏览器中cookie的路径:
后天获取的cookie情况: 后台任何目录都可以获取刚才设置cookie了。
[6]cookie的域
【域名】:俗称网址
为什么可以上网?因为交了网费。
为什么在地址栏中输出www.baidu.com就会看到百度的首页?
因为请求了百度的服务,从服务器上下载百度的首页的代码,浏览器将代码执行展示出来了。
域名 à DNS à ip地址 à 服务器
通过修改host文件调整域名的解析。
修改文件:
配置之后www.igeek.com不会再走DNS。直接指向127.0.0.1.
每个cookie都是可以设置域的
默认情况下cookie的域就是当前访问的域
注意:127.0.0.1和localhost是不同的域。
Cookie默认情况下是无法跨域的。
在访问localhost的时候产生cookie,在访问127.0.0.1的时候是不能携带过去的。
Cookie的域可以同setDomain设置域
设置的域必须是当前访问的一级域名以内。
Tips:12.7.0.0.1和localhost 都属于一级域名。
Cookie在二级域名下是可以跨域的。
修改host文件
修改设置域名的程序:将cookie的域设置为一级域名。
在www.igeek.com和ck.igeek.com两个域中cookie是可以共享的。
其实可以通过jsonp实现cookie的跨域
3.5URL重写
Session的ID默认是存储在cookie中的,cookie的name是JSESSIONID。
禁用浏览器的cookie
所有的session都失效的,因为JSESSIONID不会再存储了。
可以使用URL重写解决禁用cookie的问题。
解决登录的问题:修改day04_demo2中的loginServlet
登录之后的效果: