第十天:内置对象_四大作用域_下午面试题

来源:互联网 发布:java的所有数据类型 编辑:程序博客网 时间:2024/06/11 05:06

l  使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度。

Session技术是一种将会话状态保存在服务器端的技术,它可以比喻成是医院发放给病人的病历卡和医院为每个病人保留的病历档案的结合方式 。

客户端需要接收、记忆和回送 Session的会话标识号,Session可以且通常是借助Cookie来传递会话标识号。

 

 

 

也就是说,在第一次访问的时间,服务器为之开辟一块内存,然后通过:

Set-Cookie:JSESSIONID=99D7EEB7947AB5D40DBCCC43C66AE3C9;Path=/day10_servlet_session

发送给客户端,客户端存放的只是一个标识号,然后每次再向服务器请求时间,不是把所以的数据都发过去,而仅仅是把标识号发过去,然后服务器会给我去寻找与之相匹配的内存区域。每次发送的时间发送的是:

Cookie:JSESSIONID=99D7EEB7947AB5D40DBCCC43C66AE3C9



 

 

Cookie是存在客户端,session是存放在服务器端的,通过客户端传过来的标识符来识别。

ü  public HttpSession getSession(boolean create)

表示如果服务器内有session则返回,无论是true,还是false,当服务器那边没有session的时间,如果是true,则让服务器创建一个session返回,如果是false,发现没有session则返回null.

 

在我们开发jsp的时间,最好用<%@page session=”false”%>表示不打开session,因为很多网站不需要的,如果真的需要的时间再这样获取:

<%=session.getSession(true)%>

 

Session的超时和持久化。

 

Session的跟踪机制:

l  Servlet API规范中定义了一个HttpSession接口,HttpSession接口定义了各种管理和操作会话状态的方法。

HttpSession对象是保持会话状态信息的存储结构,一个客户端在WEB服务器端对应一个各自的HttpSession对象。

WEB服务器并不会在客户端开始访问它时就创建HttpSession对象,只有客户端访问某个能与客户端开启会话的Servlet程序时,WEB应用程序才会创建一个与该客户端对应的HttpSession对象。

WEB服务器为HttpSession对象分配一个独一无二的会话标识号,然后在响应消息中将这个会话标识号传递给客户端。客户端需要记住会话标识号,并在后续的每次访问请求中都把这个会话标识号传送给WEB服务器,WEB服务器端程序依据回传的会话标识号就知道这次请求是哪个客户端发出的,从而选择与之对应的HttpSession对象。

l  WEB应用程序创建了与某个客户端对应的HttpSession对象后,只要没有超出一个限定的空闲时间段,HttpSession对象就驻留在WEB服务器内存之中,该客户端此后访问任意的Servlet程序时,它们都使用与客户端对应的那个已存在的HttpSession对象。

HttpSession接口中专门定义了一个setAttribute方法来将对象存储到HttpSession对象中,还定义了一个getAttribute方法来检索存储在HttpSession对象中的对象,存储进HttpSession对象中的对象可以被属于同一个会话的各个请求的处理程序共享。

l  Session是实现网上商城的购物车的最佳方案,存储在某个客户Session中的一个集合对象就可充当该客户的一个购物车。

 

在上节中, 我们把cookie禁用后,就无法登陆很多网站,因为服务器发给你了一个cookie但是你不接收,你再次访问的时间,服务器检测到你没有传cookie过来,它就认为你是一个新的,还让你登陆。

 

由于<%=request.getSession()%>用的太频繁了,所以JSP里面内置了这个session对象<%=session%>不用再request获得了。在不同的环境里面得到session的方法也不同,不过使用的原理却是相同的。如struts中。

 

区别:

Cookie是客户端的个人数据保存技术,Session是服务器端的个人数据保存技术,一个浏览器来了,要找回其在服务器端的Session,通常借助Cookie实现。

 

 

利用Cookie实现Session跟踪(常规的使用):

l  如果WEB服务器处理某个访问请求时创建了新的HttpSession对象,它将把会话标识号作为一个Cookie项加入到响应消息中,通常情况下,浏览器在随后发出的访问请求中又将会话标识号以Cookie的形式回传给WEB服务器。

l  WEB服务器端程序依据回传的会话标识号就知道以前已经为该客户端创建了HttpSession对象,不必再为该客户端创建新的HttpSession对象,而是直接使用与该会话标识号匹配的HttpSession对象,通过这种方式就实现了对同一个客户端的会话状态的跟踪。

 

超链接路径要用绝对的,不相对的。

 

利用URL重写实现Session跟踪:

l  Servlet规范中引入了一种补充的会话管理机制,它允许不支持Cookie的浏览器也可以与WEB服务器保持连续的会话。这种补充机制要求在响应消息的实体内容中必须包含下一次请求的超链接,并将会话标识号作为超链接的URL地址的一个特殊参数。

l  将会话标识号以参数形式附加在超链接的URL地址后面的技术称为URL重写。如果在浏览器不支持Cookie或者关闭了Cookie功能的情况下,WEB服务器还要能够与浏览器实现有状态的会话,就必须对所有可能被客户端访问的请求路径(包括超链接、form表单的action属性设置和重定向的URL)进行URL重写。

l  HttpServletResponse接口中定义了两个用于完成URL重写方法:

ü  encodeURL方法

ü  encodeRedirectURL方法

encodeURL第一次

 

记住,我们所有编码都是服务器端编码,这一点一定要记好 。思想时间,位置要站好。

 

记住:jsp中所有的<%%>在解析的时间会被认为是一个,分开只是为了让htmljava代码分开,它们在不同的<%%>的之间的变量都是可以引用的。非常重要。

 

使用Session实现购物车:看代码,

 

Session 里面并不把集合真正存进去,而是有它的一条绳子,那么session里面存数据,存的到底是什么?有一个图说明了问题。

 

上面的代表session,下面的代表集合,集合与session之间的关系是这样的,并不是在服务器的session里面存入,应该是在一般的内存中存放,然后session那一块的内存再去调用它。

 

在使用session的时间,用的最多的是:在应用中使用最多的是getAttributesetAttribute.这两个方法负责存取服务器上的session

 

其实它是封装了JSP内部的8个内置对象,所以它成为了第九个内置对象

JSP页面往JAVA页面传东西的时间,只需要传一pageContext即可,这一个

就可以得到其它8个对象和它对应的方法。

 

<jsp:include>标签与include指令的比较

<jsp:include>标签是在当前JSP页面的执行期间插入被引入资源的输出内容,当前JSP页面与被动态引入的资源是两个彼此独立的执行实体,被动态引入的资源必须是一个能独立被WEB容器调用和执行的资源。include指令只能引入遵循JSP格式的文件,被引入文件与当前JSP文件共同合并翻译成一个Servlet的源文件。

<jsp:include>标签的作用与运行原理类似RequestDispatcher.include方法,被引入页面不能改变响应状态码和设置响应头,与此相关的语句的执行结果将被忽略。include指令没有这方面的限制。

<jsp:include>标签的执行效率要比include指令稍微差一点,但它的灵活性却要好得多。

使用<jsp:include>标签和include指令都可以把一个页面的内容分成多个组件来生成,开发者不必再把页眉和页脚部分的相同HTML代码复制到每个JSP文件中,从而可以更轻松地完成维护工作,但是都应注意最终的输出结果内容应遵循HTML语法结构,例如,如果当前页面产生了<html></html><body></body>等标记,那么在被引入文件中就不能再输出<html></html><body></body>等标记。

<jsp:include>标签对JSP引擎翻译JSP页面的过程不起作用,它是在JSP页面的执行期间才被调用,因此不会影响两个页面的编译。由于include指令是在JSP引擎翻译JSP页面的过程中被解释处理的,所以它对JSP引擎翻译JSP页面的过程起作用,如果多个JSP页面中都要用到一些相同的声明,那么就可以把这些声明语句放在一个单独的文件中编写,然后在每个JSP页面中使用include指令将那个文件包含进来。

 

因为include指令引入的文件被合并翻译到当前JSP页面中,向被引入的文件传递参数信息的做法根本就没有任何意义,它们将被JSP引擎忽略。而<jsp:include>标签可以传递参数信息和接受通过表达式动态产生的被引入资源的名称,所以,如果要用参数来控制引入的结果或动态生成引入的资源名,只能使用<jsp:include>标签。

<jsp:include>标签使用page属性指定被引入资源的相对路径,而include指令使用file属性指定被引入资源的相对路径。

假设myweb应用程序的根目录下有一个a.jsp文件,其一般的访问路径形式为:

              http://localhost:8080/myweb/a.jsp

       a.jsp页面中使用了如下语句引入b.jsp文件:

              <jsp:include page="b.jsp"flush="true" />

       请问:这时候JSP引擎调用的b.jsp文件的完整URL路径为什么?    

       如果将a.jsp页面映射为如下地址:

              http://localhost:8080/myweb/dir1/a.html

       请问:这时候JSP引擎调用的b.jsp文件的完整URL路径为:

       http://localhost:8080/myweb/b.jspf

       http://localhost:8080/myweb/dir1/b.jspf

 

 

 

 

 

关于路径问题:

<a href=<%=request.getContextPath()%>/course/ListAllCourseServlet>返回继续选课</a>

 

request.getRequestDispatcher("/WEB-INF/course/error.jsp").forward(request, response);

 

为什么绝对路径有的以项目名开头有的以项目内部开头,其实就一句话:

如果是给浏览器看的话,以项目名称开头,如果是让服务器tomcat看的话,以部署的网站内部的绝对路径开头

 

 

JSP页面中,<base href="<%=basePath%>">指本网页下的用的相对路径都是在它的基础上的,<basehref=http://localhost:8888/day10_servlet_session/
> 

 

 

<%

String path =request.getContextPath();

String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<base href="<%=basePath%>">

这个共同拼出来的,basePath.看明白了吧。

如:<basehref=http://localhost:8888/day10_servlet_session/>

 

如果绝对路径与相对路径相遇了,不行了,那么就把<base href="<%=basePath%>">

删除掉。这点非常好,要记住。

 

${course}的意思是:你这样写,首先它会在PageContext中找寻有没有这个值,然后从rqquest寻找有没有这个值,再然后从session中取值,再然后从application中取值。

如果你在前面写了范围,则直接就在指定范围内取值如${request.course}

 

<c:forEach items="${courses}"var="course">

           <tr><td>${course}</td><td><ahref="${pageContext.request.contextPath}/course/SelectCourseServlet?course=${course}">放弃</a></td></tr>

       </c:forEach>

 

 

详解:${courses}这个值,可能request,session,application中取,取到以后,每次循环的时间把值赋值给course,然后${course}值是从PageContext的里面取得的。这就是PageContext中的一个重要应用。

 

这四个作用(page,request,session,application都有setAttributegetAttribute方法,用于赋值,取值,共有四个方法:

ü  setAttribute方法

ü  getAttribute方法 

ü  removeAttribute方法

ü  getAttributeNames方法

pageContext.removeAttribute(“count”);会把所有作用域中的count都给清楚掉。

老师,pageContent.removeAttribute(“count”,PageContent.PAGE_SCOPE + PageContent.REQUEST_SCOPE),等价于你写的那两行分别清除两个作用域的代码

 

必须 要说一下,四个对象可以操作上面四个方法,不过,一个pageContext既然封装了上面8个对象,那么它就可以直接操作,

pageContext.getxxxx的某些方法,可以直接代替上面四个对象操作方法,还有一个findAttribute()这个是正是EL表达式为什么可以按照类型依次向上找的原因,因为这个就是这样的。

 

sendRedirect 浏览器发两次请求。

 

说出 JSP四个作用域,page,request,session,application

Page的类型PageContext.有若干个方法可以访问三个作用域。

ApplicationservletContext类型。

原创粉丝点击