JSP第一篇【JSP介紹、工做原理、生命週期、語法、指令、行爲】

什麼是JSP

JSP全名爲Java Server Pages,java服務器頁面。JSP是一種基於文本的程序,其特色就是HTML和Java代碼共同存在html

爲何須要JSP

JSP是爲了簡化Servlet的工做出現的替代品,Servlet輸出HTML很是困難,JSP就是替代Servlet輸出HTML的。java

簡單使用一下JSP

  • 在idea下生成一個JSP,咱們來看一下JSP長什麼樣子
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <html>
        <head>
            <title>簡單使用JSP</title>
        </head>
        <body>

        </body>
        </html>
  • 看起來就像一個HTML頁面,前面也說了:JSP的特色就是HTML和Java代碼共同存在
  • 咱們向瀏覽器輸出一句HelloWorld,至於<%%>這個東西,我先不解釋!
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <html>
        <head>
            <title>簡單使用JSP</title>
        </head>
        <body>
        <% String s = "HelloWorld"; out.println(s); %>
        </body>
        </html>

JSP的工做原理

  • 在Tomcat博客中我提到過:Tomcat訪問任何的資源都是在訪問Servlet!,固然了,JSP也不例外!JSP自己就是一種Servlet。爲何我說JSP自己就是一種Servlet呢?其實JSP在第一次被訪問的時候會被編譯爲HttpJspPage類(該類是HttpServlet的一個子類)
  • 剛纔我簡單使用了一下JSP,它被編譯成了這麼一個Servlet:
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.Date;

public final class _1_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List<String> _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.List<String> getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  }

  public void _jspDestroy() {
  }

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

    final PageContext pageContext;
    HttpSession session = null;
    final ServletContext application;
    final ServletConfig config;
    JspWriter out = null;
    final 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;

      out.write("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write(" <title>簡單使用JSP</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");

    String s = "HelloWorda";
    out.println(s);

      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}
  • 編譯過程是這樣子的:瀏覽器第一次請求1.jsp時,Tomcat會將1.jsp轉化成1_jsp.java這麼一個類,並將該文件編譯成class文件。編譯完畢後再運行class文件來響應瀏覽器的請求
  • 之後訪問1.jsp就再也不從新編譯jsp文件了,直接調用class文件來響應瀏覽器。固然了,若是Tomcat檢測到JSP頁面改動了的話,會從新編譯的
  • 既然JSP是一個Servlet,那JSP頁面中的HTML排版標籤是怎麼樣被髮送到瀏覽器的?咱們來看下上面1_jsp.java的源碼就知道了。原來就是用write()出去的罷了。說到底,JSP就是封裝了Servlet的java程序罷了。
out.write("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write(" <title>簡單使用JSP</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
  • 有人可能也會問:JSP頁面的代碼服務器是怎麼執行的?再看回1_jsp.java文件,java代碼就直接在類中的service()中。
String s = "HelloWorda";
    out.println(s);
  • JSP比Servlet更方便更簡單的一個重要緣由就是:內置了9個對象!內置對象有:out、session、response、request、config、page、application、pageContext、exception,這幾個內置對象不在這裏講。如今先知道一下便可!

JSP生命週期

JSP也是Servlet,運行時只有一個實例,JSP初始化和銷燬時也會調用Servlet的init()和destroy()方法。另外,JSP還有本身初始化和銷燬的方法 web

public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  }

  public void _jspDestroy() {
  }

JSP的語法

JSP代碼能夠分爲兩部分:express

  1. 模板數據:就是HTML代碼
  2. 元素:JSP頁面中的java代碼、JSP指令、JSP標籤

JSP腳本

  • JSP的腳本就是JSP頁面中的java代碼,也叫作scriptlet。JSP的腳本必須使用<%%>括起來,否則會被當成是模板數據的!apache

  • JSP腳本有三種方式:瀏覽器

    • <%%>【定義局部變量,編寫語句】
    • <%!%>【定義類或方法,可是沒人這樣用!
    • <%=%>(也稱之爲表達式輸出)【輸出各類類型的變量,int、double、String、Object等】
  • 若是過多地使用<%%>會致使代碼混亂,JSP還提供了一種scriptlet標籤,使用此標籤和<%%>有相同的功能,只不過它更美觀了一些tomcat

<jsp:scriptlet>

        String s = "HelloWorld";
        out.println(s);

    </jsp:scriptlet>

JSP註釋

<%--這是JSP註釋--%>
    <%--%>

    //這是java的當行註釋
    //


    /*這是java的多行註釋*/
    /**/

JSP指令

JSP指令用來聲明JSP頁面的相關屬性,例如編碼方式、文檔類型等等ruby

JSP指令的語法:服務器

<%@指令  屬性名="值"  %>

page指令

  • 我在idea生成的JSP頁面就有page指令了。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  • page指令常見屬性:markdown

  • language=」java」

  • extends=」package.class」
  • import=」{package.class | package.*}, …」
  • session=」true | false」
  • buffer=」none | 8kb | sizekb」
  • autoFlush=」true | false」
  • isThreadSafe=」true | false」
  • info=」text」
  • errorPage=」relative_url」
  • isErrorPage=」true | false」
  • contentType=」mimeType ;charset=characterSet 」 | 「text/html ; charset=ISO-8859-1」
  • pageEncoding=」characterSet | ISO-8859-1」
  • isELIgnored=」true | false」

  • 通常地,在eclipse或idea這些高級開發工具上開發,咱們只須要在page指令中指定contentType=」text/html;charset=UTF-8」,就不會出現中文亂碼問題!

  • 固然了contentType**不只僅能夠指定以text/html的方式顯示,還可使用其餘的形式顯示出來在conf/web.xml文件中能夠查詢出來**

  • 好比,我以doc形式顯示jsp的數據
<%@ page contentType="application/msword;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>簡單使用JSP</title>
    </head>
    <body>

        1111
    </body>
    </html>
  • 效果是這樣子的:

  • 咱們上網的時候,若是咱們操做不當,或者服務器出錯了,頁面都是會出現友好提示的!這個也能經過page指令來實現跳轉到友好提示頁面上
  • page指令errorPage=和isErrorPage這兩個屬性,下面咱們來看一下怎麼使用!
  • 1.jsp出現了錯誤,經過page指令的errorPage屬性跳轉到error.jsp頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" %>
    <html>
    <head>
        <title>該頁面出錯了!</title>
    </head>
    <body>
        <%--模擬頁面出錯了!!!--%>
        <% int result = 2 / 0; %>
        你好呀
    </body>
    </html>
  • error.jsp頁面要經過page指令的isErrorPage屬性設置頁面就是錯誤頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
    <html>
        <head>
            <title>友好提示頁面</title>
        </head>
        <body>
            服務器正忙着呢!
        </body>
    </html>
  • 下面是效果:

  • 固然了,細心的朋友能夠發現地址欄是沒有變化的,因此屬因而服務器跳轉。以上的作法是單個頁面設置的,若是我會有不少錯誤(JSP多的狀況下,錯誤就會多),單個設置太麻煩了!
  • 咱們能夠在web.xml文件中全局設置錯誤頁,只要發生了404錯誤或者空指針異常的錯誤都會跳轉到error.jsp頁面上
<error-page>
        <error-code>404</error-code>
        <location>/error.jsp</location>
    </error-page>

    <error-page>
        <exception-type>java.lang.NullPointerException</exception-type>
        <location>/error.jsp</location>
    </error-page>
  • 隨便輸個資源進行,會發生髮404錯誤的,跳轉到錯誤頁面。下面是效果:


include指令

  • 在講解request對象的時候,咱們曾經使用過request.getRequestDispatcher(String url).include(request,response)來對頁頭和頁尾面進行包含

  • inclue指令也是作這樣的事情,咱們來試驗一下吧!

  • 這是頁頭

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>頁頭</title>
        </head>
        <body>
        我是頁頭
        <br>
        <br>
        <br>
        </body>
    </html>
  • 這是頁尾
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>頁尾</title>
    </head>
    <body>

    我是頁尾

    </body>
    </html>
  • 在1.jsp中把頁頭和頁尾包含進來
 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>包含頁頭和頁尾進來</title> </head> <body> <%@include file="head.jsp" %> <%@include file="foot.jsp" %> </body> </html> 
  • 訪問1.jsp

  • include指令是靜態包含。靜態包含的意思就是:把文件的代碼內容都包含進來,再編譯!,看一下jsp的源代碼就知道了!

  • jsp還提供另外一種包含文件的方式:JSP行爲—動態包含。jsp行爲在下面會講到!

taglib指令

  • JSP支持標籤技術,要使用標籤技術就先得聲明標籤庫和標籤前綴。taglib指令就是用來指明JSP頁面內使用標籤庫技術。
  • 這裏就不詳細說明了,等到學習JSP標籤的時候再使用吧!如今記住有這個指令便可。

JSP行爲

JSP行爲(JSP Actions)是一組JSP內置的標籤,只書寫少許的標記代碼就可以使用JSP提供豐富的功能,JSP行爲是對經常使用的JSP功能的抽象和封裝

爲何我不把它直接稱爲JSP標籤呢?我把這些JSP內置的標籤稱之爲JSP行爲,可以和JSTL標籤區分開來。固然了,你也能夠把它稱之爲JSP標籤,你不要搞混就好了。我我的喜歡把這些JSP內置標籤稱之爲JSP行爲。

include行爲

  • 上面已經說起到了,include指令是靜態包含,include行爲是動態包含其實include行爲就是封裝了request.getRequestDispatcher(String url).include(request,response)
  • include行爲語法是這個樣子的
<jsp:include page=""/>
  • 咱們先來使用一下把,在1.jsp頁面中也將頁頭和頁尾包含進來
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>包含頁頭和頁尾進來</title>
    </head>
    <body>
        <jsp:include page="head.jsp"/>
        <jsp:include page="foot.jsp"/>
    </body>
    </html>
  • 訪問1.jsp頁面看一下效果:

  • 使用jsp行爲來包含文件,jsp源文件是這樣子的:

  • jsp行爲包含文件就是先編譯被包含的頁面,再將頁面的結果寫入到包含的頁面中(1.jsp)

  • 固然了,如今有靜態包含和動態包含,使用哪個更好呢?答案是:動態包含

  • 動態包含能夠向被包含的頁面傳遞參數(用處不大),而且是分別處理包含頁面的(將被包含頁面編譯後得出的結果再寫進包含頁面)【若是有相同名稱的參數,使用靜態包含就會報錯!】

  • 模擬一下場景吧,如今個人頭頁面有個名爲s的字符串變量

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
        <head>
            <title>頁頭</title>
        </head>
        <body>

        <% String s = "zhongfucheng"; %>
        我是頁頭呀
        <br>
        <br>
        <br>
        </body>
    </html>
  • 個人頁尾也有個名爲s的字符串變量
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>頁尾</title>
    </head>
    <body>
    <% String s = "zhongfucheng"; %>

    我是頁尾呀

    </body>
    </html>
  • 如今我使用靜態包含看看會發生什麼,出現異常了。

  • 出現異常的緣由很簡單,就是同一個文件中有兩個相同的變量s

  • 使用動態包含就能夠避免這種狀況


param行爲

  • 當使用和行爲引入或將請求轉發給其它資源時,可使用行爲向這個資源傳遞參數。

forward行爲

  • 在講解request對象的時候,咱們使用request.getRequestDispatcher(String url).forward(request,response)進行跳轉。其實forward行爲就是對其封裝
  • 咱們來看一下forward的語法:
<jsp:forward page=""/>
  • 好的,咱們來使用一下吧。訪問1.jsp頁面就跳轉到head.jsp頁面中
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>訪問1.jsp就跳轉到head.jsp</title>
    </head>
    <body>

    <jsp:forward page="head.jsp"/>


    </body>
    </html>
  • 看一下效果

  • 若是我要傳遞參數,就要在forward行爲嵌套param行爲
  • 在跳轉到head.jsp時傳入參數username值爲zhongfucheng
<jsp:forward page="head.jsp">
        <jsp:param name="username" value="zhongfucheng"/>
    </jsp:forward>
  • 在head.jsp頁面中獲取到傳遞過來的參數
<% String ss = request.getParameter("username"); %>

        獲取到的參數是:
        <%=ss%>
  • 效果以下圖所示

directive行爲

  • directive的中文意思就是指令該行爲就是替代指令<%@%>的語法的

<jsp:directive.include file="head.jsp"></jsp:directive.include>
    <jsp:directive.include file="foot.jsp"></jsp:directive.include>
  • 看下效果,正常能夠包含頁面:

  • 使用該指令可讓JSP頁面更加美觀
  • 使用scriptlet行爲<jsp:scriptlet>替代<%%>是一樣一個道理

javaBean行爲

  • JSP還提供了操做javaBean對象的行爲在這裏就不詳細說明了,後面會講到的!如今記住JSP提供了javaBean行爲來操做簡單類便可!
    • <jsp:useBean id=""/>
    • <jsp:setProperty name="" property=""/>
    • <jsp:getProperty name="" property=""/>
相關文章
相關標籤/搜索