JSP全稱jave server pages。jsp是服務端的技術,需要服務器編譯翻譯成servlet才能使用。jsp出現之前一直是HTML在做web的顯示工作,用戶通過http請求訪問網站,servlet將內部html資源跳轉過去供用戶瀏覽。但是那些靜態資源的展示不足以滿足用戶的需求,網站的定位更多的在於提高訪問量,獲取更多的用戶信息。一開始通過使用servlet的response.write()在服務端將一些動態的信息發送到顯示界面,我們的serlvet程序看起來會非常的臃腫,難以維護和擴展。於是jsp的出現很好的彌補了servlet的短板,它用來展示一些動態的數據使得開發人員的開發效率大大提高。並且簡單易學,不熟悉servlet開發的也可以使用jsp技術完成網站開發。
不能說是jsp替代了servlet,只能說它是servlet的強力助手,因爲這樣一來,我們的網站結構中servlet只業務邏輯和轉發,jsp只用來做界面展示。
在jsp中我們可以寫java代碼,也可以寫html標籤,又能使用css、jquery技術,所以說jsp是各種技術的結合,並且技術之間的耦合性幾乎沒有。
爲什麼說jsp就是sevlet
在服務器端編寫好jsp代碼時,發佈應用後,我們的web目錄中會出現work的目錄,是用來存放編譯後的jsp的.java代碼和class文件。如圖
那再來看看java文件中的內容
開頭部分的註釋是由服務器jsp引擎編寫的,指出jsp的被創建者,創建時間,最後修改時間
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.64
* Generated at: 2016-12-09 13:43:59 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
導包部分,默認的三個包和一個代碼中使用到的util的包
package org.apache.jsp.view;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
主類程序塊
public final class transfer_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() {
}
主要服務邏輯代碼,將需要展示的數據通過out對象write出各種html標籤,展示一個靜態的頁面
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("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" \t<form action=\"");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath }", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null, false));
out.write("/transferservlet\"method=\"post\">\r\n");
out.write(" \t\t<table>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td>轉入賬戶</td>\r\n");
out.write(" \t\t\t\t<td><input type=\"text\" name=\"incount\"/></td>\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td>轉出賬戶</td>\r\n");
out.write(" \t\t\t\t<td><input type=\"text\" name=\"outcount\"/></td>\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td>交易金額</td>\r\n");
out.write(" \t\t\t\t<td><input type=\"text\" name=\"money\"/></td>\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td colspan=\"2\" align=\"left\"><input type=\"submit\" value=\"確認交易\"/></td>\r\n");
out.write(" \t\t\t\t\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t</table>\r\n");
out.write(" \t</form>\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
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);
}
}
}
JSP最佳實踐,即MVC模式
在長期的實戰中,人們得出如下習慣用法:
顯示View:JSP適合做頁面的顯示,例如:顯示登錄成功界面
控制Controller:Servlet適合做業務控制操作,例如:接收用戶請求,將用戶請求的參數值封裝到JavaBean對象中去,調用其它Java類處理,如果有結果,將結果放入到域對象中去,轉發或重定向到顯示結果的JSP頁面
功能Model:Bean,即就是普通Java類,該類中封裝大量的業務操作
JSP語法
JSP輸出表達式
<%= ”xx” %>,主要用於向瀏覽器輸出變量的值
注意:<%=和%>不可分隔,後面無分號JSP腳本片斷
<% Java代碼; %>
書寫一行或多行Java代碼,多個腳本片段可以相互訪問,
注意:後面有分號,多個腳本片段之間可以相互調用JSP聲明
<%! java代碼 %>
JSP聲明的變量或方法,會被翻譯成Servlet的實例變量和成員方法JSP註釋
- JSP中可以書寫Java代碼,所有Java代碼的註釋在JSP同樣可以使用//
- JSP中可以書寫HTML代碼,所有HTML代碼的註釋在JSP同樣可以使用
- JSP也有自已特有的註釋,<%– xxxxxx –>,不能嵌套
- JSP引擎將當作有效內容,翻譯進Servlet源文件
- JSP引擎將<%– –%>當作無效內容,忽略,不翻譯進Servlet源文件,推薦使用
JSP指令 ##
JSP指令是通知JSP引擎如何處理該JSP頁面,總共三種指令:page指令、include指令、taglib指令
先扒一段頭文件指令,再一一介紹。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
- page指令
<@page [ language="java" ] 默認java, 在JSP的腳本片段只能書寫java代碼 [import="{package.class|package.*},..] 默認java.lang,javax.servlet,javax.servlet.http,javax.servlet.jsp向jsp翻譯後的servlet源碼導入包
[ session="true | false" ] 默認true,true表示一旦訪問jsp頁面,自動創建HttpSession,false表示不自動創建HttpSession.
[ autoFlush="true | false" ] 默認true,jsp頁面有緩存,在默認情況下,autoFlush=true表示緩存滿後自動強行輸出到瀏覽器,如果設置爲false的話,得通過人工調用flush()方法纔可以輸出到瀏覽器
[ isThreadSafe="true | false" ] 默認true
jsp頁面是否被多個線程同時訪問安全?
如果設置爲true,表示多個線程來訪問jsp是安全的,如果設置爲false的話,就表示該jsp頁面在沒有加鎖的情況下,多個線程來訪問,可能會出現安全問題
[ info="hello" ] 默認""表示給該jsp頁面記錄一些附加的信息
[ errorPage="relative_url" ] 無默認值,表示該jsp頁面出錯後,轉發到指定的jsp頁面進行錯誤消息的顯示
/表示當前web應用的根目錄,否則表示當前jsp頁面 [ isErrorPage="true | false" ] 默認false
如果是用於錯誤消息的顯示jsp頁面,要加isErrorPage=true這個屬性,這樣jsp引擎就會創建exception內置對象,該exception內置對象中封裝了出錯的原因.如果設置爲false的話,jsp引擎不會將exception內置對象翻譯到servlet代碼中,即無法在jsp頁面中用exception對象來獲取出錯原因
- include指令
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/jsp/date.jsp"%>
<%@ include file="/jsp/el.jsp"%>
在一個JSP頁面中包含多個其它的JSP頁面 <%@ include file=”被包含的jsp頁面的路徑”%> 在翻譯成Servlet時,就將被包含的JSP頁面中的內容翻譯成Servlet中了,即多個JSP只會翻譯成1個Servlet
- taglib指令
在JSP頁面中需要引用第三方的標籤<%@ taglib uri=”名稱空間” prefix=”標籤的前綴”%>
JSP九大內置對象
由JSP引擎將JSP翻譯成Servlet時,自動創建的對象,無需程序員創建的對象,直接使用即可,這些對象就叫內置對象。
- request : HttpServletRequest請求對象,請求域對象
- response: HttpServletResponse 響應對象
- session : HttpSession 會話域對象
- application : ServletcContext 應用域對象
- config : ServletConfig獲取某個Servlet的初始化參數
- out : JspWriter(帶緩衝的PrintWriter) JSP專用的字符輸出對象
- exception: exception (特殊情況下用) 異常對象
- page: page this(本JSP頁面) JSP頁面自己
- pageContext: 當前域對象
pageContext功能強大,其中有一個findAttribute()這個API,它會依次從page->request->session->application這幾個域對象,例如:
如果在request中找到了,就不會再去其它域對象中找了
如果在JSP中的上述四個域對象都沒找到,返回null