標籤:run 嵌套 err 開頭 eof request charset sun公司 java代碼
JSP全稱是Java Server Pages,它和servle技術一樣,都是SUN公司定義的一種用於開發動態web資源的技術。JSP這門技術的最大的特點在於,寫jsp就像在寫html,但它相比html而言,html只能為使用者提供待用資料,而Jsp技術允許在頁面中嵌套java代碼,為使用者提供動態資料。
1、JSP運行原理
當使用者第一次訪問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()方法。
2、JSP基本文法
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有自己的注釋方式,文法格式如下:
<%-- 注釋資訊 --%>
3、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" %>
4、JSP隱式對象
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指令來設定。
注意:out對象通過print寫入資料後,知道整個JSP頁面結束,out對象輸入緩衝區的資料才真正寫入到Servlet提供的緩衝區中,而Response.getWrite().print語句是直接把內容寫入到Servlet提供的緩衝區中的。
pageContext對象
JSP頁面中要想擷取隱式對象,可以使用pageContext對象,它是javax.servlet.jsp.PageContext的執行個體,代表當前JSP頁面的運行環境,並提供了一些列用於擷取其他隱式對象的方法。
方法 |
功能 |
JspWrite getOut() |
擷取out隱式對象 |
Object getPage() |
擷取page隱式對象 |
ServletRequest getRequest() |
擷取request隱式對象 |
ServletResponse getResponse() |
擷取response隱式對象 |
HttpSession getSession() |
擷取session隱式對象 |
Exception getException() |
擷取exception隱式對象 |
ServletConfig getServletConfig() |
擷取config隱式對象 |
ServletContext getServletContext() |
擷取application隱式對象 |
Java Web之JSP技術