JSP和四大作用域

 

引入:

假如說我們要在一個Servlet裏面動態的迴應一個html界面,我們應該怎麼辦呢?首先應該是

getWriter(),然後是不斷的一行一行的writer.write("html代碼");

來個簡單的還好,如果是特別多的,那這一天就什麼也不要乾了。

所以說,要學JSP

 

jsp其實可以看作是html裏面插入了java代碼,這就是jsp

jsp工作機制:

jsp本質上其實是servlet。

jsp在第一次被訪問時,會被web容器,翻譯成Servelt,在執行過程:

第一次訪問:--->index.jsp---->index.java---->編譯運行

在tomcat目錄下的work裏面可以找到,如果不懂機制怎麼運行,可以到tomcat裏面找到conf配置,打開web.xml,然後 搜.jsp然後就可以找到哪個文件了,

org.apache.jasper.servlet.JspServlet。

訪問時直接會去tomcat的work裏面找這個文件,如果有,直接用這個運行,如果沒有,把jsp對應翻譯成Servlet,java文件

jsp腳本和註釋:

jsp腳本:

<%java代碼%>

<%=java代碼%>

<%!java代碼%>

說了jsp會被web容器翻譯成servlet,那麼這三種,第一種,會在service方法中被執行。

第二種,會在service方法中,被輸出,被out輸出。獲得一個Writer

第三種,會在public裏面被弄成一個成員或者方法。

這就是第一種和第三種的區別。

jsp註釋:

<!--html註釋-->

//java單行註釋 /*多行註釋*/

<%--jsp註釋--%>

這裏需要注意的是,每種註釋的工作範圍,也就是權限。

只要抓住中心思想,就是jsp會被翻譯成Servlet文件,第三種JSP註釋,安全性最高,只能在jsp文件裏看見

第二種java註釋,翻譯到Servlet還能看得見,html裏面就看看不見了

第一種html註釋,用戶也可以看得見

jsp指令

jsp文件打開最上面一條語句是,<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

這樣式的

page 的指令是指導jsp翻譯和運行的命令,jsp包括三大指令,

1)page指令-----屬性最多的指令上面那個就是page指令

常用屬性如下:

language:jsp腳本中插入的語言

pageEncoding:當前jsp文件本身的編碼-----內部可以包含contentType,也就是說如果不寫contentType,自動和pageEncoding一樣

contentType:response.setContentType(text/htmlc;charset=UTF-8)

session:是否在jsp翻譯時候自動創建session

import:重要!導入包

errorPage:噹噹噹前頁面出錯後跳轉到哪個界面

isErrorPage:當前頁面是一個錯誤處理的界面

如果出錯了,但是errorPage有沒有處理好,那麼我們可以來一個默認的errorPage,全局的錯誤界面,也就是在這個工程下,只要出錯,就往這裏跑

操作步驟:

找到WebContent目錄下面WEB-INF裏的XML對其增加一段代碼

 <error-page>
      <error-code>404</error-code>
      <location>/error.jsp</location>
  <error-page>

include指令

 

 

 

taglib指令

作用:不知道

在jsp頁面中引入標籤庫(jstl標籤庫,struct2標籤庫)

格式:<%@ taglib uri = "標籤庫地址" prefix = "前綴"%>

jsp九大隱式對象(或者說九大內置對象)

jsp被翻譯成Servlet之後,Service方法中有九個對象定義並初始化完畢,我們在jsp腳本中,可以直接使用這九個對象(jsp腳本是啥,往上翻一翻就到了。)

名稱

類型

描述

out

javax.servlet.jsp.jspWriter

用於頁面輸出

request

javax.servlet.http.HttpServeltRequest

 

response

javax.servlet.http.HttpServletResponse

 

config

   

session

   

application

   

page

   

exception

 

如果errorPage纔是這個

pageContext

javax.servlet.jsp.pageContext

jsp的頁面容器

 

九大隱式對象不時很好記憶,那麼我們需要想着,爲什麼這九大對象可以直接拿來使用呢?

因爲咱們JSP是要翻譯成Servlet的,並且<%%>只有%沒有!的,就是在那個Service內部,那麼我們就可以想,人家在Service方法裏都定義好了!自然可以拿來用!

不妨把Service的代碼拿出來看一看

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.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;

      out.write("\r\n");
      out.write("<!DOCTYPE html>\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta charset=\"UTF-8\">\r\n");
      out.write("<title>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t");
 
		int i = 1;
		System.out.println(i);
	
      out.write('\r');
      out.write('\n');
      out.write('	');
      out.print(i );
      out.write('\r');
      out.write('\n');
      out.write('	');
      out.write('\r');
      out.write('\n');
      out.write('	');
      out.print( str );
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }

 

九大內置對象,需要講的三

out:

out的類型:不難看出,JspWriter

out的作用就是向客戶端輸出內容-------out.write(),管他孃的是什麼類型的writer,反正只要是writer,我就給你write

還記得前面三種指令中的page指令(分別是page,include,taglib),有一個屬性叫做,buffer,這個屬性這裏纔用到

下面總結一下我們的幾種輸出方式。直接代碼

在jsp<body>裏面寫進去

1111111111111111
	
	<%="222222222222222" %>
	<%
		out.write("333333333333");
		response.getWriter().write("44444444444444444444");
		
	%>

 

1.字符串11111111111的,這個本來就是html的內容,所以可以直接變成out輸出

2.222222222的,這個將會被放到out裏面去,因爲這編譯的時候會到out裏面去

3.33333333的,着個一看直接都out輸出了,沒有疑問肯定是out輸出

4.這個,特殊,是response裏面的。

buffer 和 ou&responset緩衝區

會發現,這裏輸出的時候,並不是按照我們想象的11111111 2222222222 3333333333 444444這樣的順序輸出的,而是按照4123這樣的順序

爲什麼?因爲tomcat是從response緩衝區裏面獲得內容的,我們out輸入的東西,都會被放在out的緩衝區裏面,tomcat先從response裏面獲得東西,然後再從out裏面獲取。

這就是page的屬性buffer 的作用,buffer的值代表的就是out緩衝區的大小,如果是緩衝區大小是0的話,out緩衝區沒有了,那只有寫到response裏面去了,所以就是按照順序來的。

 

pageContext:

page和pageContext對象不是一回事,page 看代碼,是頁面本身。

1)pageContext是一個域對象

四大域對象的比較

page域(就是pageContext域,簡稱)<request域<session域<application域

2)pageContext可以獲得其他八大對象,這個感覺好像是沒什麼軟用,但是後來搞框架的時候,就可以,假如method(session,request,,,,)直接傳進去一個pageContext

3)pageContext可以存參數值到任意一個域(四個域中),沒毛病。操作如下:

pageContext.setAttribute("name","zhangsan") //存到了pageContext域中

pageContext.setAttribute("name","lisi",PageContext.REQUEST_SCOPE); //存放到了request域中,等價於request.setAttribute("name","zhangsan");

pageContext.setAttribute("name","wangwu",PageContext.SESSION_SCOPE); //存到了session中

pageContext.setAttribute("name","zhaoliu",PageContext.APPLICATION_SCOPE); //存到了,application中

同樣的我們獲得也可以每個都獲得,帶個參數就可以

request.getAttribute("name");

pageContext.getAttribute("name",PageContext.REQUEST_SCOPE);

類似上面。但是pageContext還有一個屌絲的技能

pageContext.findAttribute("name");

這個雞肋的技能,是從小到大搜索域的範圍搜索name,如果有的話,就停止搜索。明白?

四大作用域的總結:

page:當前jsp的頁面範圍

request:一次請求(並不是一次會話)

session域:一次會話

application:Web應用,web服務器沒關閉。

jsp標籤(動作)

1)頁面包含(動態包含):<jsp:include page = "被包含的頁面"/>

<jsp:include file = "被包含的界面" /> //這種包含就是靜態的包含,開始的時候就直接給放到一起去了。

2) 請求轉發:<jsp:forward page = "轉發的資源" />

//這個直接,就是相當於跳轉到另外一個界面去了。但是地址欄,還是這個界面的,不要忘記了

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章