JSP全稱是Java Server Pages,它和servle技術一樣,都是SUN公司定義的一種用於開發動態web資源的技術。JSP這門技術的最大的特點在於,寫jsp就像在寫html,但它相比html而言,html只能為用戶提供靜態數據,而Jsp技術允許在頁面中嵌套java代碼,為用戶提供動態數據。
當用戶第一次訪問JSP頁面時,該頁面會被JSPServlet翻譯成一個Servlet源文件,然後將源文件翻譯成.class文件。Servlet源文件和.class文件一般放在當前Work Space下的.metadata中,可以在該目錄下搜索對應的Servlet源文件和.class文件。以下是一個簡單的JSP程序,文件名稱為index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" %> <html> <head> <title>servlet學習</title> </head> <body> <% out.println(new java.util.Date().toLocaleString()); %> </body> </html>
搜索對應的Servlet源文件和.class文件,文件結構如下所示:
可以看出,index.jsp文件被翻譯成了index_jsp.java和index_jsp.class,打開index_jsp.java文件,翻譯後的Servlet源碼如下:
/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/8.0.30 * Generated at: 2016-05-27 01:49:52 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. */ 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, org.apache.jasper.runtime.JspSourceImports { 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 static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static { _jspx_imports_packages = new java.util.HashSet<>(); _jspx_imports_packages.add("javax.servlet"); _jspx_imports_packages.add("javax.servlet.http"); _jspx_imports_packages.add("javax.servlet.jsp"); _jspx_imports_classes = null; } private volatile javax.el.ExpressionFactory _el_expressionfactory; private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public java.util.Set<java.lang.String> getPackageImports() { return _jspx_imports_packages; } public java.util.Set<java.lang.String> getClassImports() { return _jspx_imports_classes; } public javax.el.ExpressionFactory _jsp_getExpressionFactory() { if (_el_expressionfactory == null) { synchronized (this) { if (_el_expressionfactory == null) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); } } } return _el_expressionfactory; } public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { if (_jsp_instancemanager == null) { synchronized (this) { if (_jsp_instancemanager == null) { _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } } } return _jsp_instancemanager; } public void _jspInit() { } 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 java.lang.String _jspx_method = request.getMethod(); if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD"); return; } 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("<html>\r\n"); out.write("<head>\r\n"); out.write("\t<title>servlet學習</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("\t"); out.println(new java.util.Date().toLocaleString()); 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 { 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); } } }
從代碼中看出,index.jsp翻譯後的Servlet類為index_jsp,其並沒有實現Servlet接口,但是繼承了org.apache.jasper.runtime.HttpJspBase類,在Tomcat源文件中查看HttpJspBase類源碼可以得出:HttpJspBase繼承了HttpServlet,也就是說index_jsp類也是一個Servlet。HttpJspBase中的service()直接調用了_jspService()方法,也就是調用了index_jsp中的_jspService()方法。
JSP表達式
JSP表達式用於將程序數據輸出到客戶端,它將要輸出的變量或者表達式直接封裝在以"<%= expression %>"結尾的標記中。
<%= expression %>
JSP腳本片段
JSP腳本片段是指嵌套在"<%"和"%>"之中的一條或多條Java程序代碼,這些Java代碼必須遵循Java語法規范,否則編譯報錯。
<% int num = 1; out.println(num); %>
JSP聲明
當JSP頁面被翻譯成Servlet程序時,JSP包含的腳本片段、表達式、模板元素都將轉換為Servlet中_jspService()方法的程序代碼,這是,JSP腳本片段中定義的變量都將成為_jspService()中的程序代碼,這時,JSP腳本片段中定義的方法都將插入到_jspService()中,這顯然會引起語法錯誤。為了解決這個問題,在JSP提供了聲明,以"<%!"開頭,"%>"結尾。格式如下:
<%! java代碼 %>
JSP注釋
JSP有自己的注釋方式,語法格式如下:
<%-- 注釋信息 --%>
JSP2.0中定義了page、include和taglib三種指令,每種指令都定義了各自的屬性。
page指令
<%@ page 屬性名="屬性值" %>
page指令的主要常用屬性
屬性名稱 氣質范圍 功能 language java jsp文件采用的語言,默認Java import 任何報名、類名 指定導入的包或類 session true或false JSP是否內置session對象,默認session屬性為true buffer none或者數字+kb 指定緩存大小,也就是out緩沖區大小 isErrorPage true或者false 該頁面是否是錯誤處理頁面 errorPage 某個JSP頁面的路徑 制定一個錯誤處理頁使用page指令程序示例
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ page import="java.util.Date" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>servlet學習</title> </head> <body> <%= new Date() %> </body> </html>
include指令
有時在JSP頁面上需要包含一個HTML文件、文本文件時,可以通過include指令來實現,語法格式如下:
<%@ include file="relativeURL" %>
JSP頁面中,有一些對象需要頻繁使用,因此,JSP提供了9個隱式對象,他們是JSP默認創建的,可以直接在JSP頁面上使用,以下是JSP的9個隱式對象。
隱式對象名稱 類型 功能 out javax.servlet.jsp.JspWriter 頁面輸出 request javax.servlet.http.Request 得到用戶請求信息 response javax.servlet.http.Response 服務器響應信息 config javax.servlet.ServletConfig 服務器配置,可獲取初始化參數 session javax.servlet.http.HttpSession 保存用戶信息 application javax.servlet.ServletContext 所有用戶共享的信息 page java.lang.Object 當前頁面轉換後的Servlet類實例 pageContext javax.servlet.jsp.PageContext JSP頁面容器 exception java.lang.Throwable JSP頁面發生的異常,只在錯誤頁起作用out對象
JSP頁面中,需要向客戶端發送文本內容時,可以使用out對象來實現,其是javax.servlet.jsp.JspWriter的實例對象,作用和ServletResponse.getWrite()返回的PrintWrite對象類似。不同的是,out對象是一種帶緩存功能的PrintWrite,其緩沖區大小可以有page指令來設置。
方法 功能 JspWrite getOut() 獲取out隱式對象 Object getPage() 獲取page隱式對象 ServletRequest getRequest() 獲取request隱式對象 ServletResponse getResponse() 獲取response隱式對象 HttpSession getSession() 獲取session隱式對象 Exception getException() 獲取exception隱式對象 ServletConfig getServletConfig() 獲取config隱式對象 ServletContext getServletContext() 獲取application隱式對象
1、Java Web之Servlet技術
2、《Java Web程序開發入門》 第7章節
3、javaweb學習總結(十四)——JSP原理