JSP中的内置对象,是指Tomcat在翻译jsp页面成为Servlet源代码后,内部提供的九大对象,叫内置对象

九大内置对象

【1】application

  1. - ServletContext对象 <br /> - 可以理解为整个应用的一个环境对象。在一个应用中只存在一个application对象。应用一旦启动就会创建对象,停止就销毁。

【2】session

  1. - 会话对象<br />

【3】request

  • 请求对象

    【4】response

    • 响应对象

      【5】config

      • ServletConfig对象

        【6】page

    • 指向当前jsp的对象

      【7】out

      • jsp输出流对象

        【8】pageContext

    • jsp的上下文对象
      -两个主要作用:获取page作用域中的属性,获取其他的的内置对象。

      【9】exception

    • 异常对象
      -这个内置对象在错误页面才会出现。jsp提供了错误页面的配置。

      四大域对象

      pageContext (PageContextImpl类) - 当前jsp页面范围内有效 request (HttpServletRequest类) - 一次请求范围内有效 session (HttpSession类) - 一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器 ) application (ServletContext类) - 整个web工程范围内部都有效(只要web工程不停止,数据都在 )

域对象是可以像map一样存取数据的对象;四个域对象功能一样,不同的是他们对数据的存取范围

例子

scope数据请求转发scope2

——1.请求转发后只有pageContext没有数据,因为只在当前页面范围有效 ——2.关闭浏览器,打开浏览器输入http://localhost:8080/firstWeb_war_exploded/js/scope.jsp地址,发现request数据也没有了 ——3.重新启动tomcat服务器打开scope2.jsp会发现都没有数据

scope.js

  1. <body>
  2. <h1>scope.jsp页面</h1>
  3. <%
  4. //往四个域中都分别保存了数据
  5. // pageContext.setAttribute("name","pageContext");
  6. request.setAttribute("key","request");
  7. session.setAttribute("key","session");
  8. application.setAttribute("key","application");
  9. %>
  10. pageContext域是否有值:<%=request%><br/>
  11. request域是否有值:<%=request.getAttribute("key")%><br>
  12. session域是否有值:<%=session.getAttribute("key")%><br>
  13. application域是否有值:<%=application.getAttribute("key")%><br>
  14. <%-- 请求转发--%>
  15. <%
  16. request.getRequestDispatcher("/js/scope2.jsp").forward(request,response);
  17. %>
  18. </body>

scope2.js

  1. <body>
  2. <h1>scope.jsp页面</h1>
  3. pageContext域是否有值:<%=request%><br/>
  4. request域是否有值:<%=request.getAttribute("key")%><br>
  5. session域是否有值:<%=session.getAttribute("key")%><br>
  6. application域是否有值:<%=application.getAttribute("key")%><br>
  7. </body>

总结

虽然四个域都可以存储数据,但是在使用上是有优先顺序的,分别是作用范围从小到大的顺序

out输出和response.writer()的区别

response表示响应,我们经常用于设置返回给客户端的内容(输出)
out也是给用户做输出使用。

案例

  1. <body>
  2. 1
  3. <%
  4. out.write("out输出1 <br/>");
  5. out.write("out输出2 <br/>");
  6. response.getWriter().write("response输出1<br/>");
  7. response.getWriter().write("response输出2<br/>");
  8. %>
  9. </body>

客户端: response输出1 response输出2 1 out输出1 out输出2

以上代码运行完,再看看发现客户端界面会发现,事实并不是按照代码顺序执行的。
那么,为什么呢?
以下图片展示了jsp数据输出到界面的底层实现
jsp数据响应.png
out的数据会先进入out缓冲区,response数据也会进入response缓冲区,但是当jsp页面所有代码执行完毕以后,会有两个操作:

  • 执行out.flush()操作,会把out缓冲区的数据追加到response缓冲区末尾
  • 会执行response的刷新操作,把全部数据写给客户端

    验证

    我们现在验证这个想法的操作:
    在out输出1后面加一个刷新操作,给1提前刷新,看会不会提前进入response缓冲区;

    1. <body>
    2. 1
    3. <%
    4. out.write("out输出1 <br/>");
    5. out.flush();
    6. out.write("out输出2 <br/>");
    7. response.getWriter().write("response输出1<br/>");
    8. response.getWriter().write("response输出2<br/>");
    9. %>
    10. </body>

    果然不出所料,客户端的结果

    1out输出1 response输出1 response输出2 out输出2

最后,到底是用out还是response呢?
如果观察jsp翻译后后的底层源码就会发现用的都是out.write()来进行输出,所以一般情况下在jsp页面中最好统一用out输出,避免打乱界面输出内容的顺序;

out.write和out.print()

他们输出字符串的时候没有问题,但是out.write(12)有问题,不能输出整型;底层会把12转换成ascii的字符,
为什么print可以输出,因为print底层里面不管什么类型都会给你转换成字符串类型输出

结论:可以在jsp中统一使用out.print()来进行输出,前面记不住没关系,最后一句话记住就可以了