1. 程式人生 > >一篇文章帶你讀懂JSP的使用的理解

一篇文章帶你讀懂JSP的使用的理解

JSP語言是幹嘛的呢?一句話:就是在html中編寫java程式碼。能夠直接在頁面中執行並編譯,能夠訪問已經存在的類介面等,在jsp中的java與你在後臺寫的java功能一樣。相比servlet中,我們響應請求時,需要把大量的html寫在方法裡,很繁瑣。jsp就能夠在html中寫java。但是兩者貌似都有各自的弊端,servlet程式碼和頁面寫在方法中,jsp中程式碼和頁面寫在html中。儘管它的弊端很多,但是作為基礎語言,還是很有必要了解和掌握的,下面鄙人就對自己的學習理解給大家介紹使用和理解。

一:JSP的執行過程和基本指向組成。

1. 在html中編寫java程式碼,那這些java程式碼是怎麼執行的呢?誰去執行呢?其實編寫在頁面中的java程式碼還是JVM去編譯執行。

首先,在執行該JSP頁面時,伺服器會把world.jsp轉譯為world_jsp.java檔案,他就形成了一個servlet,然後生成classes檔案,再交給伺服器去執行該classes檔案,伺服器將執行完成後的結果響應給瀏覽器,並形成頁面資訊生成html,在瀏覽器中顯示出來。這就是JSP執行的過程,圖解如下:

 二: 基本內容和寫法:

<%@page contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
 
你好 JSP
 
<br>
 
<%=new Date().toLocaleString()%>

1. <%   這裡面是用來寫JAVA程式碼的    %>

2. <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>

<%@%>這種表達方式的意思是指令的意思

這是頁面內容的解釋,contentType就相當於我們在servlet中的response.setContentType("text/html;charset=UTF-8"),就是告訴瀏覽器返回來的資料用什麼內容顯示以及編碼方式是怎樣的,pageEncoding意思就是本頁面中的編碼方式是怎樣的。import這裡代表我們編寫java時需要用到的包的引用。

3. 顯示內容的寫法,也就相當於java中的print<%=%>,比如我們在jsp中的java程式碼中定義了int a = 1+1;則在頁面中顯示就可以<%=a%>,頁面中顯示2,例如我們在JSP頁面中寫一段for迴圈並且輸出。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%
    List<String> words = new ArrayList<String>();
    words.add("today");
    words.add("is");
    words.add("a");
    words.add("great");
    words.add("day");
%>
  
<table width="200px" align="center" border="1" cellspacing="0">
  
<%for (String word : words) {%>   //用<%%>包含住java程式碼
 
<tr>
    <td><%=word%></td>      //迴圈體重迴圈行和列中list的內容
</tr>
 
<%}%>     //包含住java程式碼
  
</table>

此時頁面中就會以表格的形式把list集合的數值輸出到頁面上。

4. include包含的使用:

頁面中包含另一個頁面的資訊,通常包含一些網站的公共部分,比如網頁頭,底部的版本資訊等,此時就需要用包含不然每個頁面都寫一次真的是費力勞神。我們準備一個公共的頁面:public.jsp (該jsp中輸出一句話即可)。那麼include怎麼使用呢?include有兩種使用方式,

第一種:指令include:<%@include file="public.jsp" %>,將這句話寫在你的JSP頁面中合適的位置,就會自動引用這個JSP檔案

第二種:動作include:<jsp:include page="public.jsp" />,同樣也能引用該jsp檔案顯示在當前頁面中。

那這兩種有什麼區別呢?其實就是轉譯方式不同而已,第一種指令include,他會將本身jsp和包含的jsp合併起來,然後轉譯成java檔案,然後去編譯執行,返回。而第二種動作include,就是各自轉譯各自的,public.jsp會單獨轉譯成Java檔案並執行,然後他們如何互相訪問呢,他們是在伺服器端以java檔案的形式互相訪問的,本身.java會在伺服器訪問public.java,然後把返回的結果,顯示到頁面中。明白了吧。

在include包含中,我們可以傳遞引數,指令include因為是最終會轉譯在一起,所以不需要傳參,在public.java中直接使用本身的變數即可,但是在動作include中就需要傳遞引數了,格式為:

<jsp:include page="public.jsp">
 <jsp:param name="year" value="20181023" />
 </jsp:include> 

傳遞一個name是year的引數,在public.jsp中使用的話,通過隱式物件request獲取該引數,<%=request.getParameter("name")%>即可顯示在頁面中了。其實就相當於兩個類之間傳遞引數了,通過一個request物件傳遞的。

三:JSP的跳轉、作用域以及隱式物件:

1. JSP中是如何跳轉的呢?其實JSP的跳轉就相當於servlet中的響應跳轉,是通過<%%>java程式碼快實現的,同樣也分為客戶端跳轉和伺服器端跳轉。

客戶端跳轉:在一個go.jsp檔案中,<%  response.sendRedirect("hello.jsp")   %>只寫這一句,當訪問go.jsp時,就自動跳轉到hello.jsp中去了,當然這裡也可以調到servlet一個道理。

伺服器跳轉:go.jsp中寫:request.getRequestDispatcher("hello.jsp").forward(request, response);即可完成伺服器端跳轉,也可以跳到servlet。但是jsp提供了簡單化的寫法:<jsp:forward page="hello.jsp"/>,這樣也可完成伺服器跳轉。伺服器端跳轉沒有發起新請求,而是伺服器直接去訪問了要訪問的那個檔案。

2. 隱式物件:JSP提供了很多隱式物件,一共有九個。隱式物件的意思就是,在程式碼中不需要定義,可以直接使用的物件。分別為:request,response,out ,pageContext, session,application ,page,config,exception

request代表請求物件,

response代表響應物件,

out代表輸出物件,

pageContext代表當前頁面作用域,

session代表當前會話作用域,

application代表當前所有頁面作用域也就是整個web專案,

page代表的當前物件,就相當於該jsp檔案被轉譯為servlet例項化之後的this一樣。

config物件可以獲取一些在web.xml初始化的一些引數,如下:

<servlet>
    <!-- 把 testconfig.jsp配置為一個 servlet 不止類能配置為servlet,jsp也可以-->
    <servlet-name>testconfig</servlet-name>
    <jsp-file>/testconfig.jsp</jsp-file>
    <!-- 配置初始化引數 -->
    <init-param>
        <param-name>database-ip</param-name>
        <param-value>127.0.0.1</param-value>
    </init-param>
</servlet>
<!-- 將路徑 testconfig對映到testconfig.jsp -->
<servlet-mapping>
    <servlet-name>testconfig</servlet-name>
    <url-pattern>/testconfig</url-pattern>
</servlet-mapping>

在jsp頁面中使用時:<%=config.getInitParameter("database-ip")%>通過config物件就可以獲取到初始化的引數了。不過一般很少使用。

exception物件為異常顯示,一般用來當一個jsp頁面的程式碼執行出錯了,就會跳轉到一個專門用來報錯的對不起頁面,此時就用到了exception物件了,具體使用如下:

①. 準備一個try.jsp
設定errorPage="catch.jsp",表示有異常產生的話,就交給catch.jsp處理
故意在裡面造成陣列越界異常

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" errorPage="catch.jsp"%>
<%
    int[] a = new int[10];
    a[20] = 5;
%>


②. 準備一個catch.jsp
設定 isErrorPage="true",表示當前頁面可以使用exception物件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
     
<%=exception%>

此時訪問try.jsp時,會跳轉到catch進行處理,瞭解即可

3. 作用域:

JSP一共有四個作用域,分別是:

pageContext表示當前頁面有效,requestContext表示一個請求有效,sessionContext表示一次會話有效,applicationContext表示全域性有效,所有使用者共享。

這四個作用域分別可對應四個隱式物件的使用方法:pageContext、request、session、application。這四個物件都可以通過setAttribute和getAttribute傳入或者獲取引數來傳遞資料,例如,

傳遞:application.setAttribute("name","zhangsan");獲取可以:application.getAttribute("name")

需要注意的是:request這個物件的作用域是一次請求有效,也就是說客戶端完整的一次請求這個資料可以傳遞,如果發起了新的請求,上一次請求時設定的setAttribute的值就獲取不到了,即客戶端跳轉時,無法傳遞request引數值,伺服器端跳轉時,沒有發起新請求,所以會傳遞該request的值。

四:cookie和session

cookie是用來幹嘛的呢?session又是幹嘛的呢?我們日常使用的網站通常會有提示瀏覽器記住密碼的提示,選中之後,我們以後一段時間登入該網站就不需要輸入密碼了,但是我們如果立即清除了cookie資料資訊,則就會失效,cookie就是這個作用的。

1. cookie,cookie是一種瀏覽器和伺服器互動資料的方式,它是由伺服器端建立,然後傳遞給客戶端,客戶端儲存在瀏覽器本地,當,下次訪問網頁時,直接帶著這個本地的cookie去訪問。

2.session,session的意思就是一次訪問會話,從開啟瀏覽器,訪問該網址開始,session就被建立了,知道關閉瀏覽器或者超過session的失效時間時,該session才會被回收銷燬。可以在tomcat中設定session的有效時間,在tomcat/conf/web.xml中的session-timeOut值。一般預設為30分鐘。

3. session和cookie是什麼關係呢?他們兩個其實是密不可分的,session中存放著一些資訊,每一個session都會有對應的一個sessionId,我們把這個id存放在cookie中,代表這個id對應這個session,當我們帶著這個存著sessionId的cookie去訪問伺服器時,伺服器可以根據cookie中的值快速定位到我們要訪問的session值。相當於一把鑰匙開一把鎖的含義。

五. JSTL的使用:

JSTL就是我們經常看到和使用過的c:、fmt:、sql:等標籤,也就是標準標籤庫。

1. 使用JSTL首先需要匯入相應的jar包:jstl.jar和standard.jar

2. 在頁面中通過指令告訴頁面進行設定:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>引入c:標籤。

3. c:的使用,<c:set var="name" value="${'zhang'}" scope="request" />   --   就相當於request.setAttribute("name","zhang")

<c:out value="${name}" />       相當於 <%=request.getAttribute("name")%>

<c:remove var="name" scope="request" />    相當於<%request.removeAttribute("name")%>

4. forEach的用法,上面我們講了用JSP如何迴圈的把list集合中的資料顯示出來,現在我們使用forEach來完成。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
<%
    List<String> heros = new ArrayList<String>();
    heros.add("塔姆");
    heros.add("艾克");
    heros.add("巴德");
    heros.add("雷克賽");
    heros.add("卡莉絲塔");
    request.setAttribute("heros",heros);
%> 
<!-- 使用jsp中的for迴圈來遍歷List -->
<table width="200px" align="center" border="1" cellspacing="0">
<tr>
    <td>id</td>
    <td>name</td>
</tr>   
<%
int i =0;
for (String hero : heros) {
i++;
%> 
<tr>
    <td><%=i%></td>
    <td><%=hero%></td>
</tr>  
<%}%>   
</table> 
<br>
<!-- 使用JSTL中的c:forEach 迴圈來遍歷List -->
<table width="200px" align="center" border="1" cellspacing="0">
<tr>
    <td>id</td>
    <td>name</td>
</tr>
<c:forEach items="${heros}" var="hero" varStatus="st"  >
    <tr>
        <td><c:out value="${st.count}" /></td>
        <td><c:out value="${hero}" /></td>
    </tr>
</c:forEach>
</table>

其中在forEach中 items就是需要遍歷迴圈的物件,var就是自定義的一個物件,可以自動變換型別,varStatus就是該物件的狀態。

5. JSTL中還有很多使用方法,例如fmt的格式化數字和格式化時間,fn:的對字串的處理等。這裡不再贅述

六:EL表示式

1. 這樣開頭,我們在JSP中,頁面之間傳遞引數,例如從1.jsp到2.jsp,我在1中session。setAttribute("name","zhang")那我在2中可以使用session.getAttribute("name")獲取,那用EL表示式的話可以直接<%=${name}%>即可獲取。同時如果是伺服器端傳遞回來的物件或者引數,在客戶端都可以通過${}來獲取值,簡單吧。如果是傳遞來的物件的話,並且該物件有相應的getter和setter方法,則可以直接通過.獲取物件的屬性,例如伺服器端傳回來一個hero物件,

則:<input type="text" name="hero" value="${hero.name}">可以直接呼叫hero.getName顯示該hero的name屬性。

2. 如果四個作用域同時擁有相同的key("name"),那EL表示式${name}會取誰的值呢?這就涉及到作用域優先順序的問題,從高到低分別是:pageContext>request>session>application

3. EL表示式如何獲取響應地址中傳回來的引數呢?這樣:${param:name}就可以得到引數name的值了。

4. 還有一些EL表示式進行數字驗證和判斷的使用方式,內容比較多,這裡不一一介紹了,有興趣的同學可以自行百度吧。

例如:判斷是否:${number ge 10? "成年人":"未成年人" }  判斷number是不是大於等於10,是就是成年人,否則未成年人

 

感謝大家的閱讀,以上學習筆記來自HOW2J