JSP全名爲Java Server Pages,java服務器頁面。JSP是一種基於文本的程序,其特色就是HTML和Java代碼共同存在!html
JSP是爲了簡化Servlet的工做出現的替代品,Servlet輸出HTML很是困難,JSP就是替代Servlet輸出HTML的。java
在idea下生成一個JSP,咱們來看一下JSP長什麼樣子web
%@ page contentType="text/html;charset=UTF-8" language="java" %> 簡單使用JSP
看起來就像一個HTML頁面,前面也說了:JSP的特色就是HTML和Java代碼共同存在express
咱們向瀏覽器輸出一句HelloWorld,至於<%%>這個東西,我先不解釋!apache
%@ page contentType="text/html;charset=UTF-8" language="java" %> 簡單使用JSP % String s = "HelloWorld"; out.println(s); %>
在Tomcat博客中我提到過:Tomcat訪問任何的資源都是在訪問Servlet!,固然了,JSP也不例外!JSP自己就是一種Servlet。爲何我說JSP自己就是一種Servlet呢?其實JSP在第一次被訪問的時候會被編譯爲HttpJspPage類(該類是HttpServlet的一個子類)瀏覽器
剛纔我簡單使用了一下JSP,它被編譯成了這麼一個Servlet:tomcat
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頁面改動了的話,會從新編譯的。session
既然JSP是一個Servlet,那JSP頁面中的HTML排版標籤是怎麼樣被髮送到瀏覽器的?咱們來看下上面1_jsp.java的源碼就知道了。原來就是用write()出去的罷了。說到底,JSP就是封裝了Servlet的java程序罷了。app
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也是Servlet,運行時只有一個實例,JSP初始化和銷燬時也會調用Servlet的init()和destroy()方法。另外,JSP還有本身初始化和銷燬的方法
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
JSP代碼能夠分爲兩部分:
模板數據:就是HTML代碼
元素:JSP頁面中的java代碼、JSP指令、JSP標籤
JSP的腳本就是JSP頁面中的java代碼,也叫作scriptlet。JSP的腳本必須使用<%%>括起來,否則會被當成是模板數據的!
JSP腳本有三種方式:
<%%>【定義局部變量,編寫語句】
<%!%>【定義類或方法,可是沒人這樣用!】
<%=%>(也稱之爲表達式輸出)【輸出各類類型的變量,int、double、String、Object等】
若是過多地使用<%%>會致使代碼混亂,JSP還提供了一種scriptlet標籤,使用此標籤和<%%>有相同的功能,只不過它更美觀了一些
String s = "HelloWorld"; out.println(s);
<%--這是JSP註釋--%>
<%--%>
//這是java的當行註釋
//
/*這是java的多行註釋*/
/**/
JSP指令用來聲明JSP頁面的相關屬性,例如編碼方式、文檔類型等等
JSP指令的語法:
<%@指令 屬性名="值" %>
我在idea生成的JSP頁面就有page指令了。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
page指令常見屬性:
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的數據
簡單使用JSP 1111
咱們上網的時候,若是咱們操做不當,或者服務器出錯了,頁面都是會出現友好提示的!這個也能經過page指令來實現跳轉到友好提示頁面上!
page指令errorPage=和isErrorPage這兩個屬性,下面咱們來看一下怎麼使用!
1.jsp出現了錯誤,經過page指令的errorPage屬性跳轉到error.jsp頁面上
該頁面出錯了! 你好呀
error.jsp頁面要經過page指令的isErrorPage屬性設置頁面就是錯誤頁面
友好提示頁面 服務器正忙着呢!
下面是效果:
固然了,細心的朋友能夠發現地址欄是沒有變化的,因此屬因而服務器跳轉。以上的作法是單個頁面設置的,若是我會有不少錯誤(JSP多的狀況下,錯誤就會多),單個設置太麻煩了!
咱們能夠在web.xml文件中全局設置錯誤頁,只要發生了404錯誤或者空指針異常的錯誤都會跳轉到error.jsp頁面上
404 /error.jsp java.lang.NullPointerException /error.jsp
隨便輸個資源進行,會發生髮404錯誤的,跳轉到錯誤頁面。下面是效果:
在講解request對象的時候,咱們曾經使用過request.getRequestDispatcher(String url).include(request,response)來對頁頭和頁尾面進行包含
inclue指令也是作這樣的事情,咱們來試驗一下吧!
這是頁頭
頁頭 我是頁頭
這是頁尾
頁尾 我是頁尾
在1.jsp中把頁頭和頁尾包含進來
包含頁頭和頁尾進來
訪問1.jsp
include指令是靜態包含。靜態包含的意思就是:把文件的代碼內容都包含進來,再編譯!,看一下jsp的源代碼就知道了!
jsp還提供另外一種包含文件的方式:JSP行爲---動態包含。jsp行爲在下面會講到!
JSP支持標籤技術,要使用標籤技術就先得聲明標籤庫和標籤前綴。taglib指令就是用來指明JSP頁面內使用標籤庫技術。
這裏就不詳細說明了,等到學習JSP標籤的時候再使用吧!如今記住有這個指令便可。
JSP行爲(JSP Actions)是一組JSP內置的標籤,只書寫少許的標記代碼就可以使用JSP提供豐富的功能,JSP行爲是對經常使用的JSP功能的抽象和封裝。
爲何我不把它直接稱爲JSP標籤呢?我把這些JSP內置的標籤稱之爲JSP行爲,可以和JSTL標籤區分開來。固然了,你也能夠把它稱之爲JSP標籤,你不要搞混就好了。我我的喜歡把這些JSP內置標籤稱之爲JSP行爲。
上面已經說起到了,include指令是靜態包含,include行爲是動態包含。其實include行爲就是封裝了request.getRequestDispatcher(String url).include(request,response)
include行爲語法是這個樣子的
<jsp:include page=""/>
咱們先來使用一下把,在1.jsp頁面中也將頁頭和頁尾包含進來。
包含頁頭和頁尾進來
訪問1.jsp頁面看一下效果:
使用jsp行爲來包含文件,jsp源文件是這樣子的:
jsp行爲包含文件就是先編譯被包含的頁面,再將頁面的結果寫入到包含的頁面中(1.jsp)
固然了,如今有靜態包含和動態包含,使用哪個更好呢?答案是:動態包含。
動態包含能夠向被包含的頁面傳遞參數(用處不大),而且是分別處理包含頁面的(將被包含頁面編譯後得出的結果再寫進包含頁面)【若是有相同名稱的參數,使用靜態包含就會報錯!】!
模擬一下場景吧,如今個人頭頁面有個名爲s的字符串變量
頁頭 我是頁頭呀
個人頁尾也有個名爲s的字符串變量
頁尾 我是頁尾呀
如今我使用靜態包含看看會發生什麼,出現異常了。
出現異常的緣由很簡單,就是同一個文件中有兩個相同的變量s
使用動態包含就能夠避免這種狀況
當使用jsp:include和jsp:forward行爲引入或將請求轉發給其它資源時,可使用jsp:param行爲向這個資源傳遞參數。
在講解request對象的時候,咱們使用request.getRequestDispatcher(String url).forward(request,response)進行跳轉。其實forward行爲就是對其封裝!
咱們來看一下forward的語法:
<jsp:forward page=""/>
好的,咱們來使用一下吧。訪問1.jsp頁面就跳轉到head.jsp頁面中
訪問1.jsp就跳轉到head.jsp
看一下效果
若是我要傳遞參數,就要在forward行爲嵌套param行爲
在跳轉到head.jsp時傳入參數username值爲zhongfucheng
<jsp:forward page="head.jsp">
<jsp:param name="username" value="zhongfucheng"/>
</jsp:forward>
在head.jsp頁面中獲取到傳遞過來的參數
獲取到的參數是:
效果以下圖所示
directive的中文意思就是指令。該行爲就是替代指令<%@%>的語法的
jsp:directive.page/ 至關於<%@page %>
jsp:directive.taglib/ 至關於<%@taglib %>
咱們來試一下能不能用的
<jsp:directive.include file="head.jsp"></jsp:directive.include>
<jsp:directive.include file="foot.jsp"></jsp:directive.include>
看下效果,正常能夠包含頁面:
使用該指令可讓JSP頁面更加美觀!
使用scriptlet行爲<jsp:scriptlet>
替代<%%>是一樣一個道理
JSP還提供了操做javaBean對象的行爲,在這裏就不詳細說明了,後面會講到的!如今記住JSP提供了javaBean行爲來操做簡單類便可!
<jsp:useBean id=""/>
<jsp:setProperty name="" property=""/>
<jsp:getProperty name="" property=""/>
若是文章有錯的地方歡迎指正,你們互相交流。