zoukankan      html  css  js  c++  java
  • Jsp:内置对象和四种域对象的理解

    由来:在jsp开发中,会频繁使用到一些对象 。例如HttpSession,ServletContext,ServletContext,HttpServletRequet。所以Sun公司设计Jsp时,在jsp页面加载完毕之后就会自动帮开发者创建好这些对象,开发者只需要直接使用这些对象调用方法即可!这些创建好的对象就叫内置对象,一共有九个。

    内置对象名 类型
    request HttpServletRequest
     response  HttpServletResponse
    config ServletConfig
    application ServletContext
    session Httpsession
    exception Thrwable(错误处理页面)
    page Object(this:当前jsp翻译的类如我们上次写到的hello.jsp翻译变成了hello_jsp.java中的生命周期方法)
    out JspWriter
    pageContext pageContext

    我们可以随便打开一个以jsp翻译的java源文件

    public void _jspService(HttpServletRequest request, HttpServletResponse response)
            throws java.io.IOException, ServletException {
    
        PageContext pageContext = null;
        HttpSession session = null;
        ServletContext application = null;
        ServletConfig config = null;
        JspWriter out = null;
        Object page = this;
        JspWriter _jspx_out = null;
        PageContext _jspx_page_context = null;
    
    
        try {
          response.setContentType("text/html;charset=UTF-8");
          pageContext = _jspxFactory.getPageContext(this, request, response,
          			null, true, 8192, true);
          _jspx_page_context = pageContext;
          application = pageContext.getServletContext();
          config = pageContext.getServletConfig();
          session = pageContext.getSession();
          out = pageContext.getOut();
          _jspx_out = out;
    
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    
        } 
    

      从上面可以看到内置对象都是在service方法中创建的,而指令和声明是成员变量和方法,故不能在指令和声明中使用内置对象


    1、out对象

      是jspWriter类,相当于带缓存的PrintWriter。有点与PrintWriter方法相似

      如果我们在jsp页面执行以下代码会发现

    <%
        		out.write("abc");
        		response.getWriter().write("2222223");
    %>
    

    因为out中添加了缓冲区的设置,所以在浏览器中先打印出后面的语句,前面的要等其缓冲区(默认大小是8kb)没有满,要等jsp页面执行完之后才打印,我们也可以去手动刷新页面

             

    我们可以在jsp的指令部分去设置缓冲区大小

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" buffer="8kb"%>
    

    我们继续做实验,在jsp页面运行如下的代码

    <%
        		out.write("abc");
        		//查看缓冲区的大小
        		System.out.println("当前缓冲区的大小:"+out.getBufferSize());
        		System.out.println("当前缓冲区的剩余大小:"+out.getRemaining());
     %>

    看到的结果是这样的:

    我们在浏览端发送了只有“abc”这样3个字节,却是用了两百多个字节的大小,多余的部分去哪了呢?这个时候我们可以全看看out_jsp.java文件,

     out.write("
    ");
          out.write("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    ");
          out.write("<html>
    ");
          out.write("  <head>
    ");
          out.write("    <base href="");
          out.print(basePath);
          out.write("">
    ");
          out.write("    <title>My JSP 'out.jsp' starting page</title>
    ");
          out.write("  </head>
    ");
          out.write("  <body>
    ");
          out.write("     	");
    
        		out.write("abc");
        		//查看缓冲区的大小
        		System.out.println("当前缓冲区的大小:"+out.getBufferSize());
        		System.out.println("当前缓冲区的剩余大小:"+out.getRemaining());
        	 
          out.write("
    ");
          out.write("  </body>
    ");
          out.write("</html>
    ");
    

    其实我们会发现,我们向浏览发送字节远不止abc,其实还有一些标签等的内容,他们是要发送到浏览器端,也是占大小的。

    我们再来做一个实验,如下代码,

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" buffer="1kb"%>
    <%	
    	System.out.println(out.getRemaining());
    	for(int i=1;i<=1024;i++)
    	out.write("a");
    	//查看缓冲区的大小
    	response.getWriter().write("郭庆兴");
     %>
    

    看到这个时候的效果:

    不知道为什么我这里出现了一开始的缓冲区大小是1022(我设置了应该是1kb buffer="1kb"),但是这不是我的重点,重点是他这个图说明了缓冲区的运行机制,如果缓冲区满了,就立即将其打印出来,没有满,就等待页面执行完才打印,就像第一次1022缓冲区满了之后去打印,然后又重新往里放两个a,此时缓冲区没有满,就必须等待jsp页面加载完后执行,所以出现在“郭庆兴”的后面出现。

    (我发现不知道哪里用了两个字节使得一开始的缓冲区大小只有1022B,我有试了buffer="2kb"和buffer="3kb",发现其剩余大小都正常)

    2、exception 对象

    该对象表示其他页面所抛出的异常对象(Throwable对象)

    我们打开jsp翻译后的java源文件发现,在该文件的service方法中居然里面八大内置对象都存在,就唯独没有该对象,这是因为我们没有指定其为错误处理页面,只有指定当前页面为错误错里页面后才可以去使用它。

    3、pageContext对象

    jsp的上下文对象,为了我们更方便的去使用其他八个内置对象。

    (例如当我们要在service方法之外去调用session对象或者request对象等,)

    public void _jspService(request,response){

              创建内置对象

               HttpSession session =....;

                ervletConfig config = ....;

         把8个经常使用的内置对象封装到PageContext对象中

                 PageContext pageContext  = 封装;

                 调用method1方法(如果将这八个内置对象一个一个的作为参数传递给下面的方法,显然过于麻烦,这个时候我们可以使用已经封装好了的pageContext作为参数传递过去明显就简单多了)

                  method1(pageContext);

    }

    public void method1(PageContext pageContext){

      希望使用内置对象

      从PageContext对象中获取其他8个内置对象

        JspWriter out =pageContext.getOut();

       HttpServletRequest rquest = pageContext.getRequest();

      ........

    }

     注意:pageContext也是一个域对象,已经有四个域对象了:request,servletContext,还有session,现在又有pageContext,(cookie不是域对象,而是将数据发送到浏览器端保存),那么现在servlet已经有三个域对象了,而jsp有四个域对象(jsp就是一个servlet)。

    #保存数据

        1)默认情况下,保存到page域

                  pageContext.setAttribute("name");

        2)可以向四个域对象保存数据

                  pageContext.setAttribute("name",域范围常量)

    #获取数据

      1)、默认情况下,从page域获取

                    pageContext.getAttribute("name")

      2)、可以从四个域中获取数据

          pageContext.getAttribute("name",域范围常量)

              PageContext.PAGE_SCOPE (page域)

                              PageContext.REQUEST_SCOPE(request域)

                                PageContext..SESSION_SCOPE(session域)

                                PageContext.APPLICATION_SCOPE(aplication域:即servletContext)

      3)、自动在四个域中搜索数据

                   pageContext.findAttribute("name");

        如果有相同的名字,则按照顺序:page域 -> request域 -> session域- > context域(application域)  

    我们可以来对pageContext来做实验

    <%
        	//pageContext作为域对象去保存数据
        	pageContext.setAttribute("message", "i am coming");
        	pageContext.setAttribute("message", "我是pageContext中设置的request域中的值,i am coming", pageContext.REQUEST_SCOPE);
        	//request.setAttribute("name", "gqxing");		//等价于上面的代码
        	
        	request.setAttribute("value", "request's value");
        	 %>
        	 <hr>
        	 <%--
        	 	原则:在那个域中保存数据,必须在哪个域中取数据。
        	  --%>
        	 <%
        	 	//获取数据
        	 	String message=(String)pageContext.getAttribute("message");
        	 	out.print(message+"<hr>");
        	 	String name=(String)request.getAttribute("message");
        	 	out.print(name);
        	  %>
        
        	   <hr>
        	   <span>用pageContext中的request域去取request域中设置的值(request.setAttribute("value", "request's value");)</span>
        	   <% String value=(String)pageContext.getAttribute("message", pageContext.REQUEST_SCOPE);
        	   	  out.print(value);
        	    %>
        	    <hr><span>用findattribute去查找:</span>
        	    <%--
        	    	findAttribute:自动搜索功能
        	    	顺序:page域(pageContext)——>request域——>session域——>application域。
        	    	 --%>
        	    <%
        	    	String name3=(String)pageContext.findAttribute(message);
        	    	out.print(name);
        	     %>
    

      结果如图所示:


     关于四种域对象的理解

    可以来试着去辨别各自的区别(jsp的四个域对象的作用范围)

    page域(pageContext):只能作用于当前页面,既不能用来做做转发的数据分享,也不能做重定向的数据分享

    request域:只能作用于同一个请求的数据共享,所以只能在请求的转发中使用

    session域:只能作用于一次对话中共享数据(一次对话:用户打开浏览器,浏览多个web站点后,关闭该浏览器),转发和重定向都可以使用

    context域(application):只能在同一个web应用中使用。(全局的)

    我们可以做如下的实验:

    先用请求的转发做一个实验,如下:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
    
        <title>My JSP 'demo4.jsp' starting page</title>
      </head>
      <body>
      <%--数据的保存面 --%>
        <%pageContext.setAttribute("messsage", "page'vale",pageContext.PAGE_SCOPE);
          pageContext.setAttribute("message", "request'value",pageContext.REQUEST_SCOPE);
          pageContext.setAttribute("message", "session'value",pageContext.SESSION_SCOPE);
          pageContext.setAttribute("message", "context'value", pageContext.APPLICATION_SCOPE);
         %>   
         <%
         	request.getRequestDispatcher("/demo5.jsp").forward(request, response);
          %>
      </body>
    </html>
    

      然后在另一个页面去接受数据

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
      </head>
      <body>
       page:<%=pageContext.getAttribute("message") %>
       <hr>
       request:<%=pageContext.getAttribute("message",pageContext.REQUEST_SCOPE) %>
       <hr>
       session:<%=pageContext.getAttribute("message",pageContext.SESSION_SCOPE) %>
       <hr>
       application(context):<%=pageContext.getAttribute("message",pageContext.APPLICATION_SCOPE) %>
      </body>
    </html>
    

     最后发现结果如图所示:

    当我们将转发方式改为重定向的时候,如下:

    response.sendRedirect(request.getContextPath()+"/demo5.jsp");

    这时结果如图:

  • 相关阅读:
    【转】CNN卷积神经网络_ GoogLeNet 之 Inception(V1-V4)
    【转】Caffe的solver文件配置
    python 从filelist.txt中拷贝文件到另一文件夹中
    【转】fscanf 跳过空格,读取一行
    caffe配置NCCL
    caffe实现多任务学习
    mysql 2
    mysql 1
    mysql
    jQuery
  • 原文地址:https://www.cnblogs.com/helloworldcode/p/6046582.html
Copyright © 2011-2022 走看看