時間:2023-05-30 21:57:01 | 來源:網(wǎng)站運營
時間:2023-05-30 21:57:01 來源:網(wǎng)站運營
JavaWeb詳解(第四篇)之JSP 簡介:<%@ page contentType="text/html;charset=GBK" language="java" isErrorPage="true"%><!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <% String s = "HelloWorld"; out.println(s); %></body></html>
當(dāng)我第一次訪問時,找到我們項目的部署位置:package org.apache.jsp;?import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;?public final class a_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; } //JSP也是Servlet,運行時只有一個實例 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 {? //9大內(nèi)置對象 final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request); //頁面聲明了isErrorPage="true"屬性才會有 if (exception != null) { response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } 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=GBK"); 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>/r/n"); out.write("<html>/r/n"); out.write("<head>/r/n"); out.write("<title>a.jsp</title>/r/n"); out.write("</head>/r/n"); out.write("<body>/r/n"); out.write(" <h1>我是a.jsp</h1>/r/n"); out.write(" ");? String s = "HelloWorld"; out.println(s); 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); } }}
我們發(fā)現(xiàn)有個叫a_jsp.java的文件,跟蹤原代碼看到它它繼承了HttpJspBase 類。 HttpJspBase 類又繼承了 HttpServlet 類。 也就是說。 jsp 翻譯出來的 java 類, 它間接了繼承了 HttpServlet 類。 也就是說, 翻譯出來的是一個 Servlet 程序 。細(xì)心的人可能發(fā)現(xiàn),輸出跟我們手寫的很像,是的jsp幫我們完成了這部分復(fù)雜的工作。<%@ page language="java" import="java.util.*" pageEncoding="GBK"%><%@ include file=" " %><%@ taglib prefix=" " uri="" %>
<%@ page contentType="text/html;charset=GBK" language="java" %>
page 指令中常用屬性有:語法:<%@ include file=”文件路徑” %>案例:它會把b.jsp的內(nèi)容都包含進(jìn)來,再一起編譯。<%@ include file=”b.jsp” %>
<%!聲明變量、方法和類的代碼%>
<% java代碼 %>
<%=變量或可以返回值的方法或 Java 表達(dá)式%>
//單行注釋
/*多行注釋*/
/**文檔注釋*/
java 注釋<!-- -->
會在 servlet 中生成對應(yīng)的 out.write(“<!-- -->”)
,這樣在返回給瀏覽器的靜態(tài)頁面中也有<!-- -->
,只是用戶看不到而已;<%-- --%>
則在 servlet 中沒有任何輸出,建議使用<%-- --%>JSP動作(JSP Actions)是一組JSP內(nèi)置的標(biāo)簽,只書寫少量的標(biāo)記代碼就能夠使用JSP提供豐富的功能,JSP行為是對常用的JSP功能的抽象和封裝。JSP Actions是使用 xml 語法寫的,是 jsp 規(guī)定的一些列標(biāo)準(zhǔn)動作,在容器處理 jsp 時,當(dāng)容器遇到動作元素時,就執(zhí)行相應(yīng)的操作??赡芸赐旮拍钸€是很抽象。
<jsp:forward page="跳轉(zhuǎn)的jsp頁面"> [<jsp:param name="" value=""/>] [<jsp:param name="" value=""/>] </jsp:forward>
轉(zhuǎn)發(fā)JSP Actions | 語法 | 描述 |
---|---|---|
include | <jsp:include page="relativeURL|<%=expressicry%>"></jsp:include> | 動態(tài)引入另一個文件 |
forward | <jsp:forward page="跳轉(zhuǎn)的jsp頁面">[<jsp:param name="" value=""/>][<jsp:param name="" value=""/></jsp:forward>轉(zhuǎn)發(fā) | 在開發(fā)jsp的過程中,我們通常把jsp放入WEB-INF目錄,目的是為了防止用戶直接訪問這些jsp文件.在WebRoot下我們有一個入口頁面,它的主要轉(zhuǎn)發(fā)<jsp:forward file="/WEB-INF/xx.jsp"></jsp:forward> |
param | <jsp:param name="" value=""/> | 給一個 JSP 設(shè)置參數(shù),常常與<jsp:include>或者<jsp:forward>集合使用<jsp:include page=""><jsp:param name="" value=""/><jsp:param name="" value=""/></jsp:include>,也可以給Bean或Applet傳遞參數(shù)。 |
useBean | <jsp:useBean class="" id=""></jsp:useBean> | 創(chuàng)建一個 javaBean 實例 |
setProperty | <jsp:setProperty name="對象" property="屬性" value="屬性值" scope="作用域"/> | 給一個 javaBean 實例屬性賦值 |
getProperty | <jsp:getProperty property="" name=""/> | 取得一個 javaBean 實例的成員變量 |
plugin | <sp:plugin code="" codebase="" type="bean"></jsp:plugin> | 使用插件 |
fallback | <jsp:fallback></jsp:fallback> | 指定瀏覽器不支持或無法啟動Bean或Applet時,在頁面上打印輸出信息 |
directive | <jsp:directive.include file="head.jsp"></jsp:directive.include> | 替代指令`<%@%>`的語法的 |
<jsp:include>
動作是通過 page 屬性來指定被包含頁面的,該屬性支持 JSP 表達(dá)式。<html></html>
、<body></body>
這種標(biāo)記,還要避免變量沖突)<jsp:include>
動作包含文件時,只有當(dāng)該標(biāo)記被執(zhí)行時,才會引入被包含的的頁面進(jìn)行編譯,再將譯之后的視圖再引入到當(dāng)前頁面,然后繼續(xù)執(zhí)行后面的代碼。所以被引入的頁面即使有與當(dāng)前相同的Java變量也沒影響。org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "b.jsp", out, false);
<%@ page contentType="text/html;charset=GBK" language="java"%><!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <% String s = "HelloWorld"; out.println(s); %> <jsp:forward page="b.jsp"></jsp:forward></body></html>
3)案例效果if (true) { _jspx_page_context.forward("b.jsp"); return;}
使用案例2:<jsp:forward page="b.jsp"> <jsp:param name="username" value="mjx"/> <jsp:param name="password" value="123"/></jsp:forward>
2)在b.jsp中使用我獲取到的參數(shù):<% String username = request.getParameter("username"); String password = request.getParameter("password");%><br>用戶名:<%=username %><br>密碼:<%=password %>
3)案例效果<jsp:include>
或</jsp:forword>
時可以使用param動作向這個資源傳遞參數(shù)。上面的案例中已經(jīng)使用到了,這里就不再演示了。public class User {? //------------------User類封裝的私有屬性--------------------------------------- // 姓名 String類型 private String name; // 性別 String類型 private String sex; // 年齡 int類型 private int age; //------------------User類的無參數(shù)構(gòu)造方法--------------------------------------- public User() { }? //------------------User類對外提供的用于訪問私有屬性的public方法----------------------- public String getName() { return name; }? public void setName(String name) { this.name = name; }? public String getSex() { return sex; }? public void setSex(String sex) { this.sex = sex; }? public int getAge() { return age; }? public void setAge(int age) { this.age = age; } }
在學(xué)useBean之前,我們要使用一個對象,可能會這樣寫:<%@ page contentType="text/html;charset=GBK" language="java"%><%@ page import="com.cn.domain.User" %>?<!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <% User u = new User(); u.setName("mjx"); u.setAge(18); u.setSex("男"); %> <% String userInfo = "姓名:"+u.getName() +" 性別:"+u.getSex()+" 年齡:"+u.getAge();%> <%=userInfo %></body></html>
案例效果:<jsp:useBean>
用于在指定的域范圍內(nèi)查找指定名稱的JavaBean對象。語法一(常用):<jsp:useBean id="實例化對象的名稱" class="類的全名" scope="保存范圍page|request|session|application" ></jsp:useBean>?語法二:<jsp:useBean id="stu" class="com.Bean.StudentInfo" type="com.Bean.StudentBase(父類)" scope="session" />
使用案例:<%@ page contentType="text/html;charset=GBK" language="java"%>?<!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <jsp:useBean id="user" class="com.cn.domain.User" scope="page"/> <% user.setName("mjx"); user.setAge(18); user.setSex("男"); %> <% String userInfo = "姓名:"+user.getName() +" 性別:"+user.getSex()+" 年齡:"+user.getAge();%> <%=userInfo %></body></html>
案例編譯部分源碼:com.cn.domain.User user = null;user = (com.cn.domain.User) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.PAGE_SCOPE);if (user == null){ //這里就是為什么需要一個無參構(gòu)造了 user = new com.cn.domain.User(); _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.PAGE_SCOPE);}user.setName("mjx");user.setAge(18);user.setSex("男");String userInfo = "姓名:"+user.getName() +" 性別:"+user.getSex()+" 年齡:"+user.getAge();
<jsp:setProperty>
動作標(biāo)記通常與<jsp:useBean>
動作標(biāo)記一起使用,它以請求中的參數(shù)給創(chuàng)建的JavaBean中對應(yīng)的屬性賦值,通過調(diào)用 bean 中的 setXxx() 方法來完成。<%@ page contentType="text/html;charset=GBK" language="java"%><!DOCTYPE html><html><head><title>b.jsp</title></head><body> <form action="a.jsp" method="post"> 用戶名:<input type="text" name="name"><br> 性別:<input type="text" name="sex"><br> 年齡:<input type="text" name="age"><br> <input type="submit" value="提交"> </form></body></html>
2)修改a.jsp<%@ page contentType="text/html;charset=GBK" language="java"%>?<!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <jsp:useBean id="user" class="com.cn.domain.User" scope="page"/> <% String name = request.getParameter("name"); String sex = request.getParameter("sex"); int age = Integer.parseInt(request.getParameter("age")); user.setName(name); user.setSex(sex); user.setAge(age); %> <% String userInfo = "姓名:"+user.getName() +" 性別:"+user.getSex()+" 年齡:"+user.getAge();%> <%=userInfo %></body></html>
使用案例2:<%@ page contentType="text/html;charset=GBK" language="java"%>?<!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <% request.setCharacterEncoding("GBK"); %> <jsp:useBean id="user" class="com.cn.domain.User" scope="page"/> <!--name:對象名稱 property:屬性名稱,如果指定為*號則自動匹配 value:指定值 --> <jsp:setProperty name:"user" property="name" value="自定義名字"/> <jsp:setProperty name="user" property="age"/> <jsp:setProperty name="user" property="sex" /> <% String userInfo = "姓名:"+user.getName() +" 性別:"+user.getSex()+" 年齡:"+user.getAge(); %> <%=userInfo %></body></html>
案例使用原理: org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(_jspx_page_context.findAttribute("user"), "name", "自定義名字", null, null, false); out.write("/r/n"); out.write(" "); org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(_jspx_page_context.findAttribute("user"), "age", request.getParameter("age"), request, "age", false); out.write("/r/n"); out.write(" "); org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(_jspx_page_context.findAttribute("user"), "sex", request.getParameter("sex"), request, "sex", false);
需要保持表單中的屬性名和定義的javaBean屬性名一致的原因就是,編譯后是使用request.getParameter("sex")的值。并且,類型都會幫我們自動轉(zhuǎn)換。<jsp:getProperty>
標(biāo)記用來獲得 bean中的屬性,并將其轉(zhuǎn)換為字符串,再在 JSP 頁面中輸出,該 bean 中必須具有 getXxx() 方法。<%@ page contentType="text/html;charset=GBK" language="java"%>?<!DOCTYPE html><html><head><title>a.jsp</title></head><body> <h1>我是a.jsp</h1> <% request.setCharacterEncoding("GBK"); %> <jsp:useBean id="user" class="com.cn.domain.User" scope="page"/> <%--自動匹配并設(shè)置值--%> <jsp:setProperty name="user" property="*"/> <%--自動匹配并設(shè)置值--%> 姓名:<jsp:getProperty name="user" property="name"/> 性別:<jsp:getProperty name="user" property="sex"/> 年齡:<jsp:getProperty name="user" property="age"/></body></html>
案例效果:<%@ page contentType="text/html;charset=GBK" language="java"%><!DOCTYPE html><html><head><title>c.jsp</title></head><body> <h1>我是c.jsp</h1> <% // out 輸出 out.write("這是 out 的第一次輸出<br/>"); // out flush 之后。 會把輸出的內(nèi)容寫入 writer 的緩沖區(qū)中 out.flush(); // 最后一次的輸出, 由于沒有手動 flush, 會在整個頁面輸出到客戶端的時候, 自動寫入到 writer緩沖區(qū) out.write("這是 out 的第二次輸出<br/>"); // writer 的輸出 response.getWriter().write("這是 writer 的第一次輸出<br/>"); response.getWriter().write("這是 writer 的第二次輸出<br/>"); %></body></html>
案例效果:<%@ page contentType="text/html;charset=GBK" language="java" errorPage="error.jsp" %><html><head> <title></title></head><body><%--模擬空指針異常的錯誤--%><% String isnull = null; isnull.length();%></body></html>
2)新建一個error.jsp<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK" isErrorPage="true"%><!--注意:isErrorPage="true"時才能使用exception--><!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; GBK"><title>Insert title here</title></head><body> <%out.println("程序拋出了異常:" + exception); %></body></html>
3)案例效果:官方文檔上描述:pageContext對象常用API:
PageContext 為頁面/組件作者和頁面實現(xiàn)者提供了許多工具,其中包括:
-管理各種范圍名稱空間的單個 API
-許多便捷 API,用于訪問各種公共對象
-獲取 JspWriter 以供輸出的機(jī)制
- 通過頁面管理會話使用的機(jī)制
-向腳本環(huán)境公開頁面指令屬性的機(jī)制
-將當(dāng)前請求轉(zhuǎn)發(fā)或包含到應(yīng)用程序中其他活動組件的機(jī)制
-處理 errorpage 異常處理的機(jī)制
<%@ page contentType="text/html;charset=GBK" language="java"%><!DOCTYPE html><html><head><title>e.jsp</title></head><body> <h1>我是e.jsp</h1> <% request.setAttribute("info","value of request scope"); session.setAttribute("info","value of request scope"); application.setAttribute("info","value of application scope"); %> pageContext 查找各個范圍內(nèi)的值:查找順序page—>request->session->application <br> 輸出: <%=pageContext.findAttribute("info") %> <hr> pageContext 取出以下范圍內(nèi)的值(方法一):<br> request 設(shè)定的值:<%=pageContext.getRequest().getAttribute("info") %> <br> session 設(shè)定的值:<%=pageContext.getSession().getAttribute("info") %> <br> application 設(shè)的值:<%=pageContext.getServletContext().getAttribute("info") %> <hr> pageContext取出以下范圍內(nèi)各值(方法二):<br> 范圍1(page)內(nèi)的值:<%=pageContext.getAttribute("info",1) %> <br> 范圍2(request)內(nèi)的值:<%=pageContext.getAttribute("info",2) %> <br> 范圍3(session)內(nèi)的值:<%=pageContext.getAttribute("info",3) %> <br> 范圍4(application)內(nèi)的值:<%=pageContext.getAttribute("info",4) %> <hr> pageContext 修改或刪除某個范圍內(nèi)的值: 1)修改 request 設(shè)定的值:<br> <% pageContext.setAttribute("info","value of request scope is modified by pageContext",2); %> <br> 修改后的值:<%=pageContext.getRequest().getAttribute("info") %> <br> 2)刪除 session 設(shè)定的值:<% pageContext.removeAttribute("info"); %> 刪除后的值:<%=session.getAttribute("info") %></body></html>
2)案例效果<%@ page contentType="text/html;charset=GBK" language="java"%><!DOCTYPE html><html><head><title>c.jsp</title></head><body> <h1>scope.jsp</h1> <% // 往四個域中都分別保存了數(shù)據(jù) pageContext.setAttribute("key", "pageContext"); request.setAttribute("key", "request"); session.setAttribute("key", "session"); application.setAttribute("key", "application"); %> pageContext 域是否有值: <%=pageContext.getAttribute("key")%> <br> request 域是否有值: <%=request.getAttribute("key")%> <br> session 域是否有值: <%=session.getAttribute("key")%> <br> application 域是否有值: <%=application.getAttribute("key")%> <br> <% session.setAttribute("findKey", "session"); application.setAttribute("findKey", "application"); %><br> 使用key去查找值:按作用域從小到大查<br> key:<%=pageContext.findAttribute("key")%><br> findKey:<%=pageContext.findAttribute("findKey")%></body></html>
2)案例效果關(guān)鍵詞:
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。