20210714_跳转方式,三大作用域和会话跟踪
内容
1.跳转方式:转发和重定向(必须要记忆,面试会问)
2.三大作用域(会,清楚概念)
3.会话跟踪(重点session方式进行会话跟踪)
一、转发和重定向
转发:
- req.getRequestDispatcher(“send.jsp”).forward(req, resp);
- 属于一次请求;
- 一次请求,响应的头中没有 Location;响应头中有时文件的类型,文件的大小
- 可以在request范围共享数据;

-
重定向:
resp.sendRedirect(“page/type/list.jsp”);
- 两次请求,
- 第一次请求中,响应头中有Location;并且响应码302,通过这两者共同告诉浏览器,你得重新发送请求,第二次请求中才有响应头中有时文件的类型,文件的大小
- 所有没有办法在request范围内共享数据,可以通过session或者application达到数据的共享;

使用场景:
req范围内容共享数据就是使用转发,需要使用request进行共享数据
跳转到别的应用的页面时,使用重定向,不需要request进行共享数据
二、作用域(服务端的对象)
所谓“作用域”就是“信息共享的范围”,也就是说一个信息能够在多大的范围内有效。4个JSP内置对象的作用域分别为:application、session、request、page 。JSP和Servlet内置对象作用域表如下:
| 名称 | 作用域 |
|---|---|
| *application | 在应用整个程序中有效, 相对更消耗内存 |
| *session | 在当前会话中有效,次之 |
| *request | 在当前请求中有效,消耗最小 |
| page | 在当前页面有效(jsp)就是this |
以上的这样一些对象,进行存数据和取数据,他们的方法都是一样
存值
xxx.setAttribute(key,value);以键值对的方式进行存放,key:String,value:Object
取值
xxx.getAttribute(key);通过key获取value值
删除值:
xxx.removeAttribute(key),通过key一次value
如果在这些三大作用域对象中存放数据是key相同,那么通过el表达式获取到时 request中存放的值
但是要获取指定作用域对象中存放的值 :${作用域对象(request,session,application)+Scope.key}
例如: requestScope.key , sessionScope.key ,applicationScope.key
application 作用域
可以在整个应用范围内进行共享数据
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。 整个应用是指从应用启动,到应用结束。我们说“从服务器启动,到服务器关闭”存放数据,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。 application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用(除非服务器tomcat停止了)。
使用场景:
被整个应用共享,例如:访问量,当前在线人数
session作用域
session作用域比较容易理解,同一浏览器对服务器进行多次访问,在这多次访问之间传递信息,就是session作用域的体现。如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
session是通过HttpSession接口实现的,它提供的主要方法如下所示:
Object HttpSession.getAttribute(String name) //从session中获取信息。
void HttpSession.setAttribute(String name, Object value)//向session中保存信息。
HttpSession HttpServletRequest.getSessio() //获取当前请求所在的session的对象。
session的开始时刻比较容易判断,它从浏览器发出第一个HTTP请求即可认为会话开始。但结束时刻就不好判断了,因为浏览器关闭时并不会通知服务器,所以只能通过如下这种方法判断:如果一定的时间内客户端没有反应,则认为会话结束。Tomcat的默认值为120分钟,但这个值也可以通过HttpSession的setMaxInactiveInterval()方法来设置:
使用场景:
1.需要登录了之后才能进行操作,此时可以把登录的账号,id信息存放在session中,被后期继续使用
注意:要求浏览器允许使用cookie,会话跟踪(session 和cookie的关系)
request作用域
一次请求范围内,可以进行共享数据
一个HTTP请求的处理可能需要多个Servlet合作,而这几个Servlet之间可以通过某种方式传递信息,但这个信息在请求结束后就无效了。
Servlet之间的信息共享是通过HttpServletRequest接口的两个方法来实现的:
void setAttribute(String name, Object value) //将对象value以name为名称保存到request作用域中。
Object getAttribute(String name) //从request作用域中取得指定名字的信息。
JSP中的doGet()、doPost()方法的第一个参数就是HttpServletRequest对象,使用这个对象的 setAttribute()方法即可传递信息。那么在设置好信息之后,要通过何种方式将信息传给其他的Servlet呢?这就要用到RequestDispatcher接口的forward()方法,通过它将请求转发给其他Servlet。
RequestDispatcher ServletContext.getRequestDispatcher(String path) //取得Dispatcher以便转发,path为转发的目的Servlet。
void RequestDispatcher.forward(ServletRequest request, ServletResponse response)//将request和response转发
因此,只需要在当前Servlet中先通过setAttribute()方法设置相应的属性,然后使用forward()方法进行跳转,最后在跳转到的Servlet中通过使用getAttribute()方法即可实现信息传递。
使用的场景:
一次请求范围的,使用数据,之后不再使用,request
page作用域(了解)
page对象的作用范围仅限于用户请求的当前页面,对于page对象的引用将在响应返回给客户端之后被释放,或者在请求被转发到其他地方后被释放。page里的变量只要页面跳转了,它们就不见了。如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
<%pageContext.setAttribute("kkk", 111); %>- ``
<%=pageContext.getAttribute("kkk") %>
如果以上作用域对象存值时key都是一样时,如果在jsp中进行取值需要加作用域对象,pageScope,requestScope,sessionScope,applicationScope
//servlet中的代码req.setAttribute("str1", "lucy1");//requestreq.setAttribute("name", "request中存放的name");- ``
HttpSession session=req.getSession();//获取到session对象,通过request对象提供的方法获取到的session.setAttribute("str2", "lucy2");//session中存session.setAttribute("name", "session中存放的name");- ``
ServletContext application= req.getServletContext();//整个应用范围的变量,applicationapplication.setAttribute("str3", "lucy3");//applicationapplication.setAttribute("name", "application中存放的name");- ``
req.getRequestDispatcher("/my/04.jsp").forward(req, resp);- ``
//jsp中进行取值request:${requestScope.name}<br/>session:${sessionScope.name}<br/>application:${applicationScope.name}<br/>三、会话跟踪
HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的、非连续的。
当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟踪技术就可以解决这个问题。
当一个客户在多个页面间切换时,服务器会保存该用户的信息。
通俗讲:就是为了证明客户端就是当初的哪个客户端(当初和服务器进行会话的哪客户端进行通过信息),
1)隐藏域,表单中(JSP页面)
例如:类型修改页面中,点击修改后调整到修改页面,当点击提交按钮时,修改的是当前那条数据,通过隐藏域完成<form action="update" method="post"><!-- 隐藏域 type="hidden"--><input type="hidden" name="tid" value="${type.tid }" ><br/>类型名称:<input type="text" name="tname" value="${type.tname}" ><br/>是否启用:<input type="radio" name="state" value="1" ${type.state==1?'checked':'' } >启用<input type="radio" name="state" value="0" ${type.state==0?'checked':'' } >弃用<br/>类型备注:<textarea rows="5" cols="30" name="remarks" >${type.remarks}2)URL的重写,就是在请求服务器正常资源时,携带额外的参数(key-value)
例如:进行商品类型状态的修改操作(超链接方式是最多)
http://localhost:8080/BookMall_v2.0/goodsType/changeState?tid=2&state=13)使用Cookie
1.什么是Cookie
Cookie实际上是一小段的文本信息,保存在浏览器上。每次访问该网站的网页是可以携带该信息到服务端。具体的做法是当服务端的信息希望被客户端记录下来,以便于后期访问时携带,做法比较简单,以响应头的形式给客户端,之后客户端访问该网站时就携带头信息到服务端
存值,tomcat最终以响应头的信息传输给了浏览器,浏览器将信息记忆在他的本地Cookie cookie=new Cookie("j48", "java48Class");cookie.setMaxAge(60*60*24*30);resp.addCookie(cookie);//可在浏览器端存活,浏览器不关闭就存活,关闭就销毁
取值,请求头中携带了cookie,tomcat将其存放在Request类型的对象中了
Cookie[] cs=req.getCookies();- ``
for (Cookie c : cs) {String name=c.getName();String value=c.getValue();int age=c.getMaxAge();- ``
System.out.println(name+"===>"+value+":"+age);- ``
}
//设置cookie的存活时间,不设置默认浏览器关闭就没有了
Cookie cookie= new Cookie("uid", "111111");//存放的key(String)--value(String)- ``
//cookie.setMaxAge()也可以设置cookie的有效时间,-1是临时的,浏览器关闭就没有了,0:失效现在, 还可以设置大一0的数据resp.addCookie(cookie);req.getRequestDispatcher("main.html").forward(req, resp);
4)HTTP Session(Session)
Httsession:服务端的对象
本质还是依赖于cookie的
1、概念:
Session代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续的,,一次会话过程中可以包含多次请求和响应。在Servlet中,session指的是HttpSession类的对象,是服务器端的对象,session信息会缓存在服务端
2、session创建的时间是:
HttpSession session=req.getSession(),服务端没有和当前客户端对应的session时,进行创建了session对象
由于session会消耗内存资源,能使用request存放就不适用session了
3.session进行会话跟踪流程
1)当客户端发请求,到服务端,
2)服务端创建session对象,时响应回去时在响应头中包含了一个set-cookie:jsessionid=xxxxxx,
3)浏览器根据set-cookie,会将信息保存在cookie中,key:jsessionid ,value=xxxxx
4)之后的该浏览器,发送该服务器的请求都会携带cookie信息到服务端
5)服务端tomcat会根据jsessionid找到当初创建的session对象

