jsp全名(java server pages)中文叫做java服務器頁面。在Servlet那一篇我們發現用Servlet可以生成動態頁面,但是我們卻在Servlet中卻寫了大量的html標簽,此外在Servlet中我們不得不將大量靜態顯示內容和動態生產內容混合在一起,使得我們網頁編輯人員和程序員無法一起進行研發,這樣會大大增加開發的效率,有人會說為什麼不用ajax,因為在那個時候並沒有ajax。所以為了克服這些問題,SUN公司就推出了JSP。
我們先來寫一個非常簡單的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp</title> </head> <body> <% out.print("Hello Jsp"); %> </body> </html>
這是一個非常普通的jsp如果我們打開tomcat服務器然後在服務器輸入http://localhost:8080/jsp-test/index.jsp它就會顯示Hello Jsp
當然這不是我說的重點,然後我們打開jsp編譯後的文件(位置在.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\jsp-test\org\apache\jsp)裡面有2個文件一個是index_jsp.java另一個是index_jsp.class。這2個文件就是當我們訪問jsp的時候由jsp(web)容器產生。現在我們看下index_jsp.java的內容
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> 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 javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { 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 PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n"); out.write("<title>jsp</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.print("Hello Jsp"); 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 { 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); } } }
看到這個頁面我相信大家很熟悉,可能會說這不是Servlet嗎?我們可以理解成動態的Servlet,其中_jspInit、_jspService、_jspDestroy分別對應的是Servlet中的init、service、destroy,他們具有相同的功能,他的優點顯而易見的,就不需要我們在Servlet中去寫上面我用黑體加重的代碼。這樣一來就加快了我們開發的效率。這樣一來我們就很容易理解jsp生成的過程。如下圖
然後我們在來分析一下Servlet和Jsp的區別
1:Jsp第一次需要編譯成Servlet(只編譯一次)
2:Jsp是Java和HTML可以組合成一個擴展名為.jsp的文件而Servlet直接從Html分離出來
3:側重點不同,SP側重於視圖,Servlet主要用於控制邏輯。
指令元素:主要用於為轉換階段提供整jsp頁面的相關信息,指令元素不會產生任何的輸出到當前的輸出流中(說白了就是定義一些關於JSP相關的信息)
page指令作用於整個jsp頁面,定義了許多和頁面相關的屬性,那麼我們來看看這些屬性
在我們生成的jsp頁面常常會有這條代碼<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
這上面幾個屬性就是指令元素 language表示開發的語言,contentType表示文本類型,charset和pageEncoding都表示編碼的格式
在將jsp轉成Servlet以後我們可以在_jspService的方法中可以發現response.setContentType("text/html; charset=UTF-8");那麼我們在來看其他的指令元素
<%@ page import="" %>這是是導入java的類和我們在開發中引用類的作用是一樣的,加入這個指令元素以後生成的Servlet就導入這個類。
<%@ page isELIgnored="true" %>用的比較多,表示是否啟動EL表達式 如果是Servlet2.3以前的版本默認是true,2.4以後的版本默認是false
<%@ page session="true" %>是否啟動Session 如果是false那麼Session在這個jsp就是無效的 默認是true
<%@ page errorPage="" %> 出現錯誤以後的指向的錯誤頁,此時web.xml配置的對這個就無效了
<%@ page isErrorPage="false" %> 指定這個JSP是否是別的頁面的錯誤頁 默認是false
<%@ page buffer="8kb" %> 指定out對象使用緩沖區的大小 默認值為8kb,none就是不設置緩沖區。
當然還有一些指令元素就不一一說了可以自己查閱一下,大家記住這些指令元素的范圍只能是當前頁面。
從字面意思我們知道include就是包含的意思,那麼這個指令元素到底干嘛的呢,它主要用於JSP頁面中靜態包括一個文件,這個文件可以是一個html,一個jsp頁面,一個文本文件,一段java代碼,我們來看看運行結果
先寫一個簡單的jsp頁面
1 <html> 2 <head> 3 <title>我是一個jsp靜態文件</title> 4 </head> 5 <body>i am myinclede.jsp 6 </body> 7 </html>
然後我們在index.jsp中引用
1 <%@ include file="myinclude.jsp" %>
運行結果如下
如果要是一段代碼呢然後我們把myinclede.jsp修改成如下
1 <%@ page import="java.util.*" %> 2 <html> 3 <head> 4 <title>我是一個jsp靜態文件</title> 5 </head> 6 <body> 7 <% 8 out.print(new Date().toLocaleString()); 9 %> 10 </body> 11 </html>
我們在此運行結果如下
這個指令用戶自定義標簽
tablib有三個屬性分別是uri、tagdir、prefi,這個在以後的自定義標簽中詳細講解(暫時簡單介紹)
腳本元素包括三個部分分別為聲明、腳本段、表達式
這個和在java代碼中聲明一個變量或方法一樣,我們來看下它的寫法
<%! int i=1; %>
<% out.print(i); %>
聲明以後我們就可以直接使用這個變量了,記住聲明要在%後面要加上!
當然你也可以聲明一個方法如下
<%! public String getUserName(){ return "zhangsan"; } %> <% out.print(getUserName());%>
腳本段是在請求處理期間要執行的java代碼<% %>裡面的代碼,這個就不多說了<% out.print(getUserName());%>就算。
表達式腳本元素是java語言完成的表達式,在請求計算這些完整表達式時會把結果轉成字符串,插入當前的輸入流中,表達式以<%=開始 %>結束
比喻姓名:<%= "張三"%>這個就是一個表達式(這個後面不需要添加如何符號)
與 JSP指令元素不同的是,JSP動作元素在請求處理階段起作用。JSP動作元素是用XML語法寫成的。標准的jsp動作元素主要有20種,下面我主要拿常用的說一下
1:<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>
<jsp:useBean>動作用來加載一個將在JSP頁面中使用的JavaBean,它的屬性有id為對象對一個名,class指定Bean的完整包名,scope表示這個對象的范圍
<jsp:setProperty>主要來設置對象值,其中name就是bean對象名,
<jsp:getProperty>主要來獲取對象的,我們來看下例子
public class UserBean { private String userName; private String realName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; }
<body> <jsp:useBean id="user" class="com.lp.beans.UserBean" scope="session"></jsp:useBean> <jsp:setProperty property="userName" name="user" value="zhangsan" /> <jsp:setProperty property="realName" name="user" value="張三"/> 用戶名:<jsp:getProperty property="userName" name="user" /> 真實姓名:<jsp:getProperty property="realName" name="user" /> </body>
運行結果:
2:<jsp:forward page=""></jsp:forward>這個和上面那個forward作用相同,跳轉地址的。
3:<jsp:include page=""></jsp:include>包含頁面,作用上面也有提及
其他的我這裡不做提及,現在開發用這個估計是不多了,想了解的可以自己看看
在Servlet中我們看到有許多對象比喻Request,response等那麼Jsp中有嗎,我們說過Jsp是動態的Servlet當然會有這些,我們來看看Jsp的9中內置對象
4.1:request
4.2:response
4.3:out,out的對象是JspWriter
4.4:page是jsp轉換成Servlet以後的實例object page=this;
4.5:pageContext來獲取當前頁面所有的屬性
4.6:application是javax.servlet.ServletContext的實例。
4.7:config是javax.servlet.ServletConfig實例
4.8:session
4.9:exception這個表示異常處理
這個我們一看應該都會明白
jsp4種范圍
5.1:request:只在請求一次service有效
5.2:page只在當前頁有效,跳出此頁就無效
5.3:Session在整個會話期間有效
5.4:application在整個應用程序中有效,知道服務器關閉