轉載自:https://www.cnblogs.com/xdp-gacl/p/3788369.htmlhtml
JSP標籤也稱之爲Jsp Action(JSP動做)元素,它用於在Jsp頁面中提供業務邏輯功能,避免在JSP頁面中直接編寫java代碼,形成jsp頁面難以維護。java
jsp的經常使用標籤有如下三個web
<jsp:include>標籤用於把另一個資源的輸出內容插入進當前JSP頁面的輸出內容之中,這種在JSP頁面執行時的引入方式稱之爲動態引入。
語法:
<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />
page屬性用於指定被引入資源的相對路徑,它也能夠經過執行一個表達式來得到。
flush屬性指定在插入其餘資源的輸出內容時,是否先將當前JSP頁面的已輸出的內容刷新到客戶端。 express
範例:使用jsp:include標籤引入資源apache
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>jsp的jsp:include標籤測試</title> 6 </head> 7 8 <body> 9 <%--使用jsp:include標籤引入其它JSP頁面--%> 10 <jsp:include page="/jspfragments/head.jsp"/> 11 <h1>網頁主體內容</h1> 12 <jsp:include page="/jspfragments/foot.jsp"/> 13 </body> 14 </html>
運行結果:瀏覽器
<jsp:include>標籤是動態引入, <jsp:include>標籤涉及到的2個JSP頁面會被翻譯成2個servlet,這2個servlet的內容在執行時進行合併。
include指令是靜態引入,涉及到的2個JSP頁面會被翻譯成一個servlet,其內容是在源文件級別進行合併。tomcat
經過下面的例子來講明<jsp:include>標籤與include指令的區別服務器
demo.jsp:架構
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%! 3 int i=1000; 4 %> 5 <h1>demo.jsp中i的值爲:<%=i%></h1>
分別使用include指令和<jsp:include>標籤兩種包含語句,包含以上的demo.jspapp
範例:使用@include包含內容
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%! 3 int i=10; 4 %> 5 <h1>JspIncludeTagDemo01.jsp中i的值爲:<%=i%></h1> 6 <h1><%@include file="/jspfragments/demo.jsp"%></h1>
此時在編譯jsp時就已經提示出錯了,以下所示:
這個錯誤說的是變量i已經重複定義了
運行JspIncludeTagDemo01.jsp,結果以下:
運行後發現出現了重複定義變量i的錯誤提示信息,由於靜態包含是將所有內容包含進來以後,再進行處理,屬於先包含後處理。因爲被包含進來的頁面demo.jsp中定義了一個變量i,而包含頁面JspIncludeTagDemo01.jsp自己又定義了一個變量i,因此服務器在處理JspIncludeTagDemo01.jsp這個頁面時就會發現裏面有兩個重複定義的變量i,所以就會報錯。
而若是如今使用的是<jsp:include>動態包含的話,觀察如下程序:
範例:使用動態包含
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1>JspIncludeTagDemo02.jsp</h1> 3 <%! 4 int i=10; 5 %> 6 7 <h1>JspIncludeTagDemo02.jsp中i的值爲:<%=i%></h1> 8 <h1><jsp:include page="/jspfragments/demo.jsp" /></h1>
運行結果:
發現結果已經能夠正確地顯示,並且不會互相影響,這是由於使用jsp:include屬於動態包含,動態包含就是指先將各個頁面分別處理,處理完以後再將處理後的結果包含進來。
不論是<jsp:include>標籤,仍是include指令,它們都會把兩個JSP頁面內容合併輸出,因此這兩個頁面不要出現重複的HTML全局架構標籤,不然輸出給客戶端的內容將會是一個格式混亂的HTML文檔。
JSP規範建議使用.jspf(JSP fragments)做爲靜態引入文件的擴展名。今天無心中發現,把一個JSP文件命名爲jspf擴展名,而後include到另外一個jsp文件中的,發現只有用"@include"指令的時候,jspf文件的內容纔會被解析並執行其中的jsp指令和tag,而使用"jsp:include"和JSTL的"c:import"都沒有用,jspf文件被看成純文本文件處理了。
好比如今有一個head.jspf頁面和foot.jspf頁面
head.jspf
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1 style="color:red;">網頁頭部</h1>
foot.jspf
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1 style="color:blue;">網頁尾部</h1>
首先使用"@include"指令將"head.jspf和foot.jspf" include到IncludeTagTest.jsp頁面,以下所示:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>jsp的Include指令測試</title> 6 </head> 7 8 <body> 9 <%--使用include標籤引入引入jspf頁面--%> 10 <%@include file="/jspfragments/head.jspf" %> 11 <h1>網頁主體內容</h1> 12 <%@include file="/jspfragments/foot.jspf" %> 13 </body> 14 </html>
運行IncludeTagTest.jsp頁面,運行結果以下:
jspf文件的內容會被解析並執行其中的jsp指令和tag,查看瀏覽器解析JspIncludeTagTest.jsp頁面生成的源代碼,以下所示:
而後再使用<jsp:include>"標籤將"head.jspf和foot.jspf" include到JspIncludeTagTest.jsp頁面中,以下所示:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>jsp的jsp:include標籤測試</title> 6 </head> 7 8 <body> 9 <%--使用jsp:include標籤引入其它JSPf頁面--%> 10 <jsp:include page="/jspfragments/head.jspf"/> 11 <h1>網頁主體內容</h1> 12 <jsp:include page="/jspfragments/foot.jspf"/> 13 </body> 14 </html>
運行JspIncludeTagTest.jsp頁面,運行結果以下:
查看瀏覽器解析JspIncludeTagTest.jsp頁面生成的源代碼,以下所示:
能夠看到,head.jspf和foot.jspf中的<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>沒有解析執行,而是原封不動地做爲文本內容輸出到頁面上了,在IE下看不到<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>的輸出,在google和火狐瀏覽器下運行能夠看到頁面上輸出<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>,以下所示:
這說明jspf文件Tomcat服務器被看成純文本文件處理了,沒有看成jsp頁面來解析執行,那麼該如何解決這個問題呢?如何讓tomcat服務器可以解析執行*.jspf文件中的java代碼和標籤呢,有以下的幾種解決辦法:
解決辦法一:修改web.xml文件,添加對擴展名爲*.jspf文件的映射
以下所示:
1 <!-- 讓jspf擴展名一樣成爲JSP Servlet處理的文件。 --> 2 <servlet-mapping> 3 <servlet-name>jsp</servlet-name> 4 <url-pattern>*.jspf</url-pattern> 5 </servlet-mapping> 6 <!-- 讓jsp擴展名一樣成爲JSP Servlet處理的文件。 --> 7 <servlet-mapping> 8 <servlet-name>jsp</servlet-name> 9 <url-pattern>*.jsp</url-pattern> 10 </servlet-mapping>
上面的配置方式也能夠簡寫成這樣:
1 <servlet-mapping> 2 <servlet-name>jsp</servlet-name> 3 <url-pattern>*.jsp</url-pattern> 4 <!-- 讓jspf擴展名一樣成爲JSP Servlet處理的文件。--> 5 <url-pattern>*.jspf</url-pattern> 6 </servlet-mapping>
兩種寫法的效果都是同樣的。
添加這樣的配置信息後,此時tomcat服務器就能夠正常解析執行*.jspf文件了,以下所示:
解決辦法二:修改Tomcat服務器的web.xml文件,添加對擴展名爲*.jspf文件的映射
找到tomcat服務器的web.xml文件,以下所示:
找到名字爲jsp的那個Servlet,以下所示:
1 <servlet> 2 <servlet-name>jsp</servlet-name> 3 <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> 4 <init-param> 5 <param-name>fork</param-name> 6 <param-value>false</param-value> 7 </init-param> 8 <init-param> 9 <param-name>xpoweredBy</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 <load-on-startup>3</load-on-startup> 13 </servlet>
而後根據Servlet名找到對應的servlet-mapping配置,以下所示:
1 <!-- The mappings for the JSP servlet --> 2 <servlet-mapping> 3 <servlet-name>jsp</servlet-name> 4 <url-pattern>*.jsp</url-pattern> 5 <url-pattern>*.jspx</url-pattern> 6 </servlet-mapping>
在這裏能夠看到,名字爲jsp的那個Servlet只支持*.jsp和*.jspx兩種擴展名,所以能夠在這個地方添加多一個<url-pattern>*.jspf</url-pattern>,以下所示:
1 <!-- The mappings for the JSP servlet --> 2 <servlet-mapping> 3 <servlet-name>jsp</servlet-name> 4 <url-pattern>*.jsp</url-pattern> 5 <url-pattern>*.jspx</url-pattern> 6 <url-pattern>*.jspf</url-pattern> 7 </servlet-mapping>
通過這樣的配置以後,Tomcat服務器就能夠正常解析和執行*.jspf文件了。
<jsp:forward>標籤用於把請求轉發給另一個資源。
語法:
<jsp:forward page="relativeURL | <%=expression%>" />
page屬性用於指定請求轉發到的資源的相對路徑,它也能夠經過執行一個表達式來得到。
範例:使用<jsp:forward>標籤跳轉頁面
forwarddemo01.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%--使用<jsp:forward>標籤跳轉到forwarddemo02.jsp--%> 3 <jsp:forward page="/forwarddemo02.jsp"/>
forwarddemo02.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1>跳轉以後的頁面!!</h1>
運行結果以下:
從頁面的顯示效果來看,頁面已經完成了跳轉,但地址欄沒有變化,地址欄中顯示的地址仍是forwarddemo01.jsp,但頁面顯示的內容倒是forwardemo02.jsp中的內容。由於此跳轉屬於服務器端跳轉。只要是服務器端跳轉,則地址欄永遠沒有變化。
當使用<jsp:include>和<jsp:forward>標籤引入或將請求轉發給其它資源時,可使用<jsp:param>標籤向這個資源傳遞參數。
語法1:
<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
語法2:
<jsp:forward page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
<jsp:param>標籤的name屬性用於指定參數名,value屬性用於指定參數值。在<jsp:include>和<jsp:forward>標籤中可使用多個<jsp:param>標籤來傳遞多個參數。
範例:使用<jsp:param>標籤向被包含的頁面傳遞參數
JspIncludeTagDemo03.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1>JspIncludeTagDemo03.jsp</h1> 3 <hr/> 4 <jsp:include page="/jspfragments/Inc.jsp"> 5 <jsp:param name="parm1" value="hello" /> 6 <jsp:param name="parm2" value="gacl" /> 7 </jsp:include>
Inc.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1>接收從JspIncludeTagDemo03.jsp頁面中傳遞過來的參數:</h1> 3 <h2><%=request.getParameter("parm1")%></h2> 4 <h2><%=request.getParameter("parm2")%></h2>
在JspIncludeTagDemo03.jsp頁面中使用<jsp:include>標籤將Inc.jsp頁面包含進來,使用<jsp:param/>標籤向Inc.jsp頁面傳遞了兩個參數parm1和parm2
JspIncludeTagDemo03.jsp頁面運行結果以下:
範例:使用<jsp:param>標籤向要跳轉的頁面傳遞參數
forwarddemo03.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%--使用<jsp:forward>標籤跳轉到forwarddemo04.jsp--%> 3 <%--使用<jsp:param>標籤向forwarddemo04.jsp傳遞參數--%> 4 <jsp:forward page="/forwarddemo04.jsp"> 5 <jsp:param name="ref1" value="hello" /> 6 <jsp:param name="ref2" value="gacl" /> 7 </jsp:forward>
forwarddemo04.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <h1>跳轉以後的頁面!!</h1> 3 <h1>接收從forwarddemo03.jsp傳遞過來的參數:</h1> 4 <h1>ref1:<%=request.getParameter("ref1")%></h1> 5 <h1>ref2:<%=request.getParameter("ref2")%></h1>
運行結果以下: