jsp初步認識 與其servlet編譯原理
前面只是介紹一點概念。
JSP的編譯原理:
jsp實際上一個Servlet物件
參看tomcat目錄下的各專案的work目錄,生成的jsp編譯成的.java檔案
jsp頁面:
<span style="color:#000000;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>login</title> <script type="text/javascript"> /* function imgUpdate(){ var imgNode= document.getElementsByTagName("img").item(0); //瀏覽器的快取,對相同url的請求無效,改變引數來達到重新整理 var t=new Date().getTime(); imgNode.src="/WebStudy/Captcha?"+t; }*/ onload=function(){ var value=document.getElementById("has").value; if(value=="true"){ alert("使用者已存在"); } var value=document.getElementById("add").value; if(value=="true") alert("使用者建立成功"); else if(value=="false") alert("使用者建立失敗"); }; </script> </head> <body> <!-- /WebStudy/Captcha 對servelt的請求,需要在web.xml配置servel的路徑對映url-pattern <img src="/WebStudy/Captcha"/><a href="javascript:imgUpdate()">看不清</a> <a href="OneServelt">一次轉發</a> <a href="/WebStudy/OneServelt">一次轉發</a> <a href="">多次轉發</a> <a href="ChongServelt">重定向</a>--> <form action="LoginServlet" method="post"> 姓名:<input type="text" name="name"/> 密碼:<input type="password" name="pwd"/> <input type="submit" value="提交"> <input type="hidden" value="<%=request.getAttribute("has") %>" id="has"> <input type="hidden" value="<%=request.getParameter("add") %>" id="add"> </form> <a href="LoginServlet">檢視所有使用者</a> <a href="MyServletConfig">配置引數</a> <a href="MyConTextServlet">留言板</a> <a href="PicServlet">picDown</a> <a href="RequestServlet">request</a> <form action="RequestServlet" method="post" enctype="application/x-www-form-urlencoded"> Name:<input type="text" name="name"/><br/> Age:<input type="text" name="age"/><br/> 愛好: <input type="checkbox" name="hoby" value="MUSIC"/>音樂 <input type="checkbox" name="hoby" value="MTV"/>電視 <input type="checkbox" name="hoby" value="driver"/>開車<br/> 性別: <input type="radio" name="sex" value="0" checked="checked"/>男 <input type="radio" name="sex" value="1"/>女 <input type="submit" value="提交"/> </form> <form action="UploadServlet" method="post" enctype="multipart/form-data"> Name:<input type="text" name="name"/><br/> Age:<input type="text" name="age"/><br/> 愛好: <input type="checkbox" name="hoby" value="MUSIC"/>音樂 <input type="checkbox" name="hoby" value="MTV"/>電視 <input type="checkbox" name="hoby" value="driver"/>開車<br/> 性別: <input type="radio" name="sex" value="0" checked="checked"/>男 <input type="radio" name="sex" value="1"/>女 上傳檔案: <input type="file" name="txtFile"> <input type="file" name="imgFile"> <input type="submit" value="提交"/> </form> <a href="cookieServlet">Cookie</a> <a href="show.jsp">圖片</a><br/> <a href="jsCookie.jsp">js操作Cookie</a><br/> <a href="sessionServlet">session</a> <form action="getServlet" method="post"> Name:<input type="text" name="name"/><br/> Age:<input type="text" name="age"/><br/> <input type="submit" value="提交"/> </form> 驗證碼: <form action="validateServlet" method="post"> Name:<input type="text" name="name"/><br/> Age:<input type="text" name="age"/><br/> <img src="bufImgServlet"><input type="text" name="validate"/><br/> <input type="submit" value="提交"/> </form> </body> </html></span>
編譯後的.java檔案
<span style="color:#000000;">package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import java.util.*; 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() { } </span><pre name="code" class="java"> public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { <span style="color:#FF0000;"> 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;</span> 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("\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(" <title>login</title>\r\n"); out.write("\t<script type=\"text/javascript\">\r\n"); out.write("\t /* function imgUpdate(){\r\n"); out.write("\t var imgNode= document.getElementsByTagName(\"img\").item(0);\r\n"); out.write("\t //瀏覽器的快取,對相同url的請求無效,改變引數來達到重新整理\r\n"); out.write("\t var t=new Date().getTime();\r\n"); out.write("\t imgNode.src=\"/WebStudy/Captcha?\"+t;\r\n"); out.write("\t }*/\r\n"); out.write("\t onload=function(){\r\n"); out.write("\t var value=document.getElementById(\"has\").value;\r\n"); out.write("\t if(value==\"true\"){\r\n"); out.write("\t alert(\"使用者已存在\");\r\n"); out.write("\t }\r\n"); out.write("\t var value=document.getElementById(\"add\").value;\r\n"); out.write("\t \r\n"); out.write("\t if(value==\"true\")\r\n"); out.write("\t alert(\"使用者建立成功\");\r\n"); out.write("\t else if(value==\"false\")\r\n"); out.write("\t alert(\"使用者建立失敗\");\r\n"); out.write("\t \r\n"); out.write("\t };\r\n"); out.write("\t</script>\r\n"); out.write(" </head>\r\n"); out.write(" \r\n"); out.write(" <body>\r\n"); out.write(" <!-- /WebStudy/Captcha 對servelt的請求,需要在web.xml配置servel的路徑對映url-pattern \r\n"); out.write(" <img src=\"/WebStudy/Captcha\"/><a href=\"javascript:imgUpdate()\">看不清</a>\r\n"); out.write(" <a href=\"OneServelt\">一次轉發</a>\r\n"); out.write(" <a href=\"/WebStudy/OneServelt\">一次轉發</a>\r\n"); out.write(" <a href=\"\">多次轉發</a>\r\n"); out.write(" <a href=\"ChongServelt\">重定向</a>-->\r\n"); out.write(" <form action=\"LoginServlet\" method=\"post\">\r\n"); out.write(" 姓名:<input type=\"text\" name=\"name\"/>\r\n"); out.write(" 密碼:<input type=\"password\" name=\"pwd\"/>\r\n"); out.write(" <input type=\"submit\" value=\"提交\">\r\n"); out.write(" <input type=\"hidden\" value=\""); out.print(request.getAttribute("has") ); out.write("\" id=\"has\"> \r\n"); out.write(" <input type=\"hidden\" value=\""); out.print(request.getParameter("add") ); out.write("\" id=\"add\"> \r\n"); out.write(" </form>\r\n"); out.write(" <a href=\"LoginServlet\">檢視所有使用者</a>\r\n"); out.write(" <a href=\"MyServletConfig\">配置引數</a>\r\n"); out.write(" <a href=\"MyConTextServlet\">留言板</a>\r\n"); out.write(" <a href=\"PicServlet\">picDown</a>\r\n"); out.write(" <a href=\"RequestServlet\">request</a>\r\n"); out.write(" <form action=\"RequestServlet\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">\r\n"); out.write(" Name:<input type=\"text\" name=\"name\"/><br/>\r\n"); out.write(" Age:<input type=\"text\" name=\"age\"/><br/>\r\n"); out.write(" 愛好:\r\n"); out.write(" <input type=\"checkbox\" name=\"hoby\" value=\"MUSIC\"/>音樂 \r\n"); out.write(" <input type=\"checkbox\" name=\"hoby\" value=\"MTV\"/>電視 \r\n"); out.write(" <input type=\"checkbox\" name=\"hoby\" value=\"driver\"/>開車<br/>\r\n"); out.write(" 性別:\r\n"); out.write(" <input type=\"radio\" name=\"sex\" value=\"0\" checked=\"checked\"/>男 \r\n"); out.write(" <input type=\"radio\" name=\"sex\" value=\"1\"/>女\r\n"); out.write(" <input type=\"submit\" value=\"提交\"/>\r\n"); out.write(" </form>\r\n");
out.write(" <form action=\"UploadServlet\" method=\"post\" enctype=\"multipart/form-data\">\r\n");
out.write(" Name:<input type=\"text\" name=\"name\"/><br/>\r\n");
out.write(" Age:<input type=\"text\" name=\"age\"/><br/>\r\n");
out.write(" 愛好:\r\n");
out.write(" <input type=\"checkbox\" name=\"hoby\" value=\"MUSIC\"/>音樂 \r\n");
out.write(" <input type=\"checkbox\" name=\"hoby\" value=\"MTV\"/>電視 \r\n");
out.write(" <input type=\"checkbox\" name=\"hoby\" value=\"driver\"/>開車<br/>\r\n");
out.write(" 性別:\r\n");
out.write(" <input type=\"radio\" name=\"sex\" value=\"0\" checked=\"checked\"/>男 \r\n");
out.write(" <input type=\"radio\" name=\"sex\" value=\"1\"/>女\r\n");
out.write(" 上傳檔案:\r\n");
out.write(" <input type=\"file\" name=\"txtFile\">\r\n");
out.write(" <input type=\"file\" name=\"imgFile\">\r\n");
out.write(" <input type=\"submit\" value=\"提交\"/>\r\n");
out.write(" </form>\r\n");
out.write(" <a href=\"cookieServlet\">Cookie</a>\r\n");
out.write(" <a href=\"show.jsp\">圖片</a><br/>\r\n");
out.write(" <a href=\"jsCookie.jsp\">js操作Cookie</a><br/>\r\n");
out.write(" <a href=\"sessionServlet\">session</a>\r\n");
out.write(" <form action=\"getServlet\" method=\"post\">\r\n");
out.write(" Name:<input type=\"text\" name=\"name\"/><br/>\r\n");
out.write(" Age:<input type=\"text\" name=\"age\"/><br/>\r\n");
out.write(" <input type=\"submit\" value=\"提交\"/>\r\n");
out.write(" </form>\r\n");
out.write(" 驗證碼:\r\n");
out.write(" <form action=\"validateServlet\" method=\"post\">\r\n");
out.write(" Name:<input type=\"text\" name=\"name\"/><br/>\r\n");
out.write(" Age:<input type=\"text\" name=\"age\"/><br/>\r\n");
out.write(" <img src=\"bufImgServlet\"><input type=\"text\" name=\"validate\"/><br/>\r\n");
out.write(" <input type=\"submit\" value=\"提交\"/>\r\n");
out.write(" </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 { 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編譯後是一個public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
jsp頁面中的html程式碼全部以PrintWrite.wirte()列印流輸出。將jsp頁面的java程式碼複製到_jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)這個函式的相應的位置執行
下來看一下org.apache.jasper.runtime.HttpJspBase是否是一個Servlet?package org.apache.jasper.runtime;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;
import org.apache.jasper.compiler.Localizer;
<span style="color:#FF0000;">public abstract class HttpJspBase extends HttpServlet</span>
implements HttpJspPage
{
private static final long serialVersionUID = 1L;
public final void init(ServletConfig config)
throws ServletException
{
super.init(config);
jspInit();
_jspInit();
}
public String getServletInfo()
{
return Localizer.getMessage("jsp.engine.info");
}
public final void destroy()
{
jspDestroy();
_jspDestroy();
}
public final void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
_jspService(request, response);
}</span>
public void jspInit()
{
}
public void _jspInit()
{
}
public void jspDestroy()
{
}
protected void _jspDestroy()
{
}
public abstract void _jspService(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
throws ServletException, IOException;
}
可以發現org.apache.jasper.runtime.HttpJspBase這就是一個抽象的servlet,那麼是servlet,就會呼叫其中的service方法,而HttpJspBase覆蓋了,呼叫_jspService方法,顯然我們的jsp編譯後形成的servlet是一個實現了httpjspbase的方法,因此呼叫了我們子類自己的_jspService方法。
既然jsp編譯執行時就是一個servlet,那麼在看servlet中有什麼
隱含物件?為什麼Java程式碼的物件變數不需要什麼宣告定義就能使用?
<span style="color:#000000;">
public void _jspService(final javax.servlet.http.HttpServletRequest <span style="color:#FF0000;">request</span>, final javax.servlet.http.HttpServletResponse <span style="color:#FF0000;">response</span>)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext <span style="color:#FF0000;">pageContext;</span>
javax.servlet.http.HttpSession <span style="color:#FF0000;">session</span> = null;
final javax.servlet.ServletContext <span style="color:#FF0000;">application</span>;
final javax.servlet.ServletConfig <span style="color:#FF0000;">config</span>;
javax.servlet.jsp.JspWriter <span style="color:#FF0000;">out</span> = null;
final java.lang.Object <span style="color:#FF0000;">page</span> = this;
javax.servlet.jsp.JspWriter <span style="color:#FF0000;">_jspx_out</span> = null;
javax.servlet.jsp.PageContext <span style="color:#FF0000;">_jspx_page_context</span> = 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;</span>
在編譯後的檔案中,我們發現。原來這些變數,tomcat早已經幫我宣告定義好了,並非不定義(java程式碼是強型別語句,絕對沒有一個變數不定義就可以用)
因此我們就可以使用這些jsp的九大變量了。
既然jsp是一個servlet,我們可以自己定義session,config,servletcontext等等物件變量了
JSP的語法:
我們知道jsp中可以有多段<% %>java程式碼,實際上就是將這些程式碼複製到_jspservice方法中去,此處定義的全是該函式的區域性變數
如果想在jsp中新增函式,即:在servlet寫函式,那麼需要<%! %>此處程式碼不會複製到jspservice方法中,而是定義成類成員變數
註釋:<%-- --%>
快速輸出:<%= %>,我們常疑惑,變數為什麼不加;號。因為在編譯時會將其中的程式碼複製到out.print()函式中作為函式引數,一個函式引數怎麼能有;號?
<%@ %>這個有三大屬性:page,include,taglib
靜態匯入和動態匯入區別:
1:靜態:調入的介面是將程式碼複製到呼叫jsp頁面中,編譯時只生成一個servlet;動態採取req,resp的傳參,編譯時生成各自的servlet檔案
2:區域性變數在靜態匯入是共享的,動態不共享區域性變數
3: 靜態包含發生成編譯時。動態包含發生在執行時。由於靜態包含最終編譯成一個Servlet檔案,所以在執行時,它的執行效率要高於動態包含。
請求轉發:
jsp異常處理: