jsp看這篇文章就夠了

原文鏈接:blog.ouyangsihai.cn >> jsp看這篇文章就夠了

一、JSP基礎語法

1、JSP模板元素

JSP頁面中的HTML內容稱之為JSP模版元素。

JSP模版元素定義了網頁的基本骨架,即定義了頁面的結構和外觀。

2、JSP腳本片段

JSP腳本片斷(scriptlet)用于在JSP頁面中編寫多行Java代碼(在<%%>不能定義方法)。語法:<%多行java代碼 %>

例如:

<%
    int num = 0;
    num = ++num;
    out.println("num:" + num);
%>
image

注意:

1、JSP腳本片斷中只能出現java代碼,不能出現其它模板元素, JSP引擎在翻譯JSP頁面中,會將JSP腳本片斷中的Java代碼將被原封不動地放到Servlet的_jspService方法中。

2、JSP腳本片斷中的Java代碼必須嚴格遵循Java語法,例如,每執行語句后面必須用分號(;)結束。

3、在一個JSP頁面中可以有多個腳本片斷,在兩個或多個腳本片斷之間可以嵌入文本、HTML標記和其他JSP元素。

4、多個腳本片斷中的代碼可以相互訪問

精彩內容推薦

3、JSP表達式

JSP腳本表達式(expression)用于將程序數據輸出到客戶端,語法:<%=變量或表達式 %>

例如:



<%="123" %>


image

4、JSP聲明

JSP頁面中編寫的所有代碼,默認會翻譯到servlet的service方法中, 而Jsp聲明中的java代碼被翻譯到_jspService方法的外面。語法:<%!java代碼 %>

JSP聲明可用于定義JSP頁面轉換成的Servlet程序的靜態代碼塊、成員變量和方法。

例如:

<%!
static { 
    System.out.println("靜態代碼塊"); 
}
 
private String name = "Zender";
 
public void TestFun(){
    System.out.println("成員方法!");
}
%>
<%
    TestFun();
    out.println("name:" + name);
%>

控制臺:

image

頁面:

image

5、JSP注釋

在JSP中,注釋有顯式注釋, 隱式注釋,JSP自己的注釋:

顯式注釋 直接使用HTML風格的注釋:<!- - 注釋內容- ->
隱式注釋 直接使用JAVA的注釋://、/……/
JSP自己的注釋 <%- - 注釋內容- -%>

區別:

HTML的注釋在瀏覽器中查看源文件的時候是可以看得到的,而JAVA注釋和JSP注釋在瀏覽器中查看源文件時是看不到注釋的內容的。

二、JSP原理

1、Web服務器是如何調用并執行一個jsp頁面的?

瀏覽器向服務器發請求,不管訪問的是什么資源,其實都是在訪問Servlet,所以當訪問一個jsp頁面時,其實也是在訪問一個Servlet,服務器在執行jsp的時候,首先把jsp翻譯成一個Servlet,所以我們訪問jsp時,其實不是在訪問jsp,而是在訪問jsp翻譯過后的那個Servlet。

例如下面的代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%!
    static { 
        System.out.println("靜態代碼塊"); 
    }
 
    private String name = "Zender";
 
    public void TestFun(){
        System.out.println("成員方法!");
    }
    %>
    <%
        TestFun();
        out.println("name:" + name);
    %>
</body>
</html>

當我們通過瀏覽器訪問index.jsp時,服務器首先將index.jsp翻譯成一個index_jsp.class,在Tomcat服務器的work\Catalina\localhost\項目名\org\apache\jsp目錄下可以看到index_jsp.class的源代碼文件index_jsp.java

image

index_jsp.java的代碼如下:

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 {
 
 
    static { 
        System.out.println("靜態代碼塊"); 
    }
 
    private String name = "Zender";
 
    public void TestFun(){
        System.out.println("成員方法!");
    }
    
  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 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 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 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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("<title>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t");
      out.write('\r');
      out.write('\n');
      out.write('   ');
 
        TestFun();
        out.println("name:" + name);
    
      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這個類是繼承org.apache.jasper.runtime.HttpJspBase這個類的,通過查看HttpJspBase源代碼,可以知道HttpJspBase類是繼承HttpServlet的,所以HttpJspBase類是一個Servlet,而index_jsp又是繼承HttpJspBase類的,所以index_jsp類也是一個Servlet,所以當瀏覽器訪問服務器上的index.jsp頁面時,其實就是在訪問index_jsp這個Servlet,index_jsp這個Servlet使用_jspService這個方法處理請求。

HttpJspBase源碼如下:

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 javax.servlet.jsp.JspFactory;
 
import org.apache.jasper.compiler.Localizer;
 
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage{
   
    protected HttpJspBase() {
    }
 
    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();
    }
 
    /**
     * Entry point into service.
     */
    public final void service(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException 
    {
        _jspService(request, response);
    }
    
    public void jspInit() {
    }
 
    public void _jspInit() {
    }
 
    public void jspDestroy() {
    }
 
    protected void _jspDestroy() {
    }
 
    public abstract void _jspService(HttpServletRequest request, 
                     HttpServletResponse response) 
    throws ServletException, IOException;
}

2、_jspService方法

問題1:Jsp頁面中的html排版標簽是如何被發送到客戶端的?

瀏覽器接收到的這些數據,都是在_jspService方法中使用如下的代碼輸出給瀏覽器的。

問題2:Jsp頁面中的java代碼服務器是如何執行的?

在jsp中編寫的java代碼會被翻譯到_jspService方法中去,當執行_jspService方法處理請求時,就會執行在jsp編寫的java代碼了,所以Jsp頁面中的java代碼服務器是通過調用_jspService方法處理請求時執行的。

3、jsp在服務器的執行流程

第一次執行:

  1. 客戶端通過電腦連接服務器,因為是請求是動態的,所以所有的請求交給WEB容器來處理
  2. 在容器中找到需要執行的*.jsp文件
  3. 之后*.jsp文件通過轉換變為*.java文件
  4. *.java文件經過編譯后,形成*.class文件
  5. 最終服務器要執行形成的*.class文件

第二次執行:

  1. 因為已經存在了*.class文件,所以不在需要轉換和編譯的過程

修改后執行:

  1. 源文件已經被修改過了,所以需要重新轉換,重新編譯。

三、JSP指令

JSP指令(directive)是為JSP引擎而設計的,它們并不直接產生任何可見輸出,而只是告訴引擎如何處理JSP頁面中的其余部分。

1、Page指令

page指令用于定義JSP頁面的各種屬性,無論page指令出現在JSP頁面中的什么地方,它作用的都是整個JSP頁面,為了保持程序的可讀性和遵循良好的編程習慣,page指令最好是放在整個JSP頁面的起始位置。

page指令的完整語法:

<%@ page 
    [ language="java" ] 
    [ extends="package.class" ] 
    [ import="{package.class | package.*}, ..." ] 
    [ session="true | false" ] 
    [ buffer="none | 8kb | sizekb" ] 
    [ autoFlush="true | false" ] 
    [ isThreadSafe="true | false" ] 
    [ info="text" ] 
    [ errorPage="relative_url" ] 
    [ isErrorPage="true | false" ] 
    [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] 
    [ pageEncoding="characterSet | ISO-8859-1" ] 
    [ isELIgnored="true | false" ] 
%>

import屬性

可以在一條page指令的import屬性中引入多個類或包,其中的每個包或類之間使用逗號(,)分隔



<%@ page import="java.util.*,java.io.*,java.sql.*"%>


備注:

在Jsp頁面中,Jsp引擎會自動導入下面的包

java.lang.*

javax.servlet.*

javax.servlet.jsp.*

javax.servlet.http.*

errorPage屬性

使用errorPage屬性指明出錯后跳轉的錯誤頁面,errorPage屬性的設置值必須使用相對路徑,如果以"/"開頭,表示相對于當前Web應用程序的根目錄,否則,表示相對于當前頁面。

image

比如index.jsp頁面有如下的代碼:

<%@ page language="java" errorPage="/error.jsp" contentType="text/html; charset=UTF-8"
            pageEncoding="UTF-8"%>
        <%
            String path = request.getContextPath();
            String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
        %>
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
        <html>
        <head>
        <base href="<%=basePath%>">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
        </head>
        <body>
            <%
              //錯誤代碼
              int x = 1/0;
            %>
        </body>
        </html>

在index.jsp中,page指令的errorPage屬性指明了出錯后跳轉到"/error.jsp",error.jsp頁面代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>error jsp</title>
</head>
<body>
        <h1>對不起,出錯了,請聯系網站管理員解決!</h1>
</body>
</html>

運行結果如下:

image

我們也可以在在web.xml中使用<error-page>標簽為整個web應用設置錯誤處理頁面,web.xml的代碼下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>JSP</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <!-- 404錯誤的處理頁面 -->
  <error-page>
      <error-code>404</error-code>
      <location>/error.jsp</location>
  </error-page>
</web-app>

error.jsp頁面代碼同上

當訪問一個不存在的web資源時,就會跳轉到在web.xml中配置的404錯誤處理頁面error.jsp,如下圖所示:

image

一個jsp頁面是作為系統的錯誤處理頁面,那么建議將page指令的isErrorPage屬性(默認為false)設置為"true"來顯式聲明這個Jsp頁面是一個錯誤處理頁面。



<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>


將error.jsp頁面顯式聲明為錯誤處理頁面后,Jsp引擎在將jsp頁面翻譯成Servlet的時候,在Servlet的 _jspService方法中會聲明一個exception對象,然后將運行jsp出錯的異常信息存儲到exception對象中,由于Servlet的_jspService方法中聲明了exception對象,那么就可以在error.jsp頁面中使用exception對象。源碼如下:

image

2、include指令

在JSP中對于包含有兩種語句形式:

  1. @include指令

    include指令用于引入其它JSP頁面,如果使用include指令引入了其它JSP頁面,那么JSP引擎將把這兩個JSP翻譯成一個servlet。所以include指令引入通常也稱之為靜態引入。

    語法:<%@ include file="relativeURL"%>

    file屬性用于指定被引入文件的路徑。路徑以"/"開頭,表示代表當前web應用。

    注意細節:

    1. 被引入的文件必須遵循JSP語法。
    2. 被引入的文件可以使用任意的擴展名,即使其擴展名是html,JSP引擎也會按照處理jsp頁面的方式處理它里面的內容,為了見明知意,JSP規范建議使用.jspf(JSP fragments(片段))作為靜態引入文件的擴展名。
    3. 由于使用include指令將會涉及到2個JSP頁面,并會把2個JSP翻譯成一個servlet,所以這2個JSP頁面的指令不能沖突(除了pageEncoding和導包除外)。
  2. <jsp:include>標簽

    <jsp:include>標簽用于把另外一個資源的輸出內容插入進當前JSP頁面的輸出內容之中,這種在JSP頁面執行時的引入方式稱之為動態引入。

    語法:<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

    page屬性:用于指定被引入資源的相對路徑,它也可以通過執行一個表達式來獲得。

    flush屬性:指定在插入其他資源的輸出內容時,是否先將當前JSP頁面的已輸出的內容刷新到客戶端。

  3. <jsp:include>標簽與include指令的區別

    <jsp:include>標簽是動態引入, <jsp:include>標簽涉及到的2個JSP頁面會被翻譯成2個servlet,這2個servlet的內容在執行時進行合并。 而include指令是靜態引入,涉及到的2個JSP頁面會被翻譯成一個servlet,其內容是在源文件級別進行合并。

四、JSP中的九個內置對象

名稱 類型 描述
out javax.servlet.jsp.JspWriter 用于頁面輸出
request javax.servlet.http.HttpServletRequest 得到用戶請求信息,
response javax.servlet.http.HttpServletResponse 服務器向客戶端的回應信息
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頁面所發生的異常,在錯誤頁中才起作用

1、page

page對象表示當前一個JSP頁面,可以理解為一個對象本身

2、out

out對象用于向客戶端發送文本數據。

3、pageContext

pageContext對象是JSP技術中最重要的一個對象,它代表JSP頁面的運行環境,這個對象不僅封裝了對其它8大隱式對象的引用,它自身還是一個域對象(容器),可以用來保存數據。并且,這個對象還封裝了web開發中經常涉及到的一些常用操作,例如引入和跳轉其它資源、檢索其它域對象中的屬性等。

通過pageContext獲得其他對象:

getException方法 返回exception隱式對象
getPage方法 返回page隱式對象
getRequest方法 返回request隱式對象
getResponse方法 返回response隱式對象
getServletConfig方法 返回config隱式對象
getServletContext方法 返回application隱式對象
getSession方法 返回session隱式對象
getOut方法 返回out隱式對象

pageContext作為域對象

pageContext對象可以作為容器來使用,因此可以將一些數據存儲在pageContext對象中。

pageContext對象的常用方法:

setAttribute(String name,Object value) 添加一個名稱為name的屬性,值為value
getAttribute(String name) 獲取名稱為name的屬性
removeAttribute(String name) 移除名稱為name的屬性
findAttribute(String name) 根據name查找各個域中的屬性

當使用findAttribute查找某個屬性時,findAttribute方法按照查找順序"page→request→session→application"在這四個對象中去查找,只要找到了就返回屬性值,如果四個對象都沒有找到要查找的屬性,則返回一個null。

五、JSP屬性范圍

JSP中提供了四種屬性范圍,如下:

當前頁(pageContext):一個屬性只能在一個頁面中取得,跳轉到其他頁面無法取得

一次服務器請求(request):一個頁面中設置的屬性,只要經過了服務器跳轉,則跳轉之后的頁面可以繼續取得。

一次會話(session):一個用戶設置的內容,只要是與此用戶相關的頁面都可以訪問(一個會話表示一個人,這個人設置的東西只要這個人不走,就依然有效)

上下文中(application):在整個服務器上設置的屬性,所有人都可以訪問

1、page屬性范圍(pageContext)

在一個頁面設置的屬性,跳轉到其他頁面就無法訪問了。但是在使用page屬性范圍的時候必須注意的是,雖然習慣上將頁面范圍的屬性稱為page范圍,但是實際上操作的時候是使用pageContext內置對象完成的。

例如:

<%@ page language="java" errorPage="/error.jsp" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%
        pageContext.setAttribute("name","Zender");
    
        String name = (String)pageContext.getAttribute("name");
    %>
        name:<%=name %>
</body>
</html>

運行結果如下:

image

使用<jsp:forward page="/index2.jsp" />標簽進行服務器跳轉到index2.jsp

Index.jsp

<%@ page language="java" errorPage="/error.jsp" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%
        pageContext.setAttribute("name","Zender");
    %>
    <%--使用jsp:forward標簽進行服務器端跳轉--%>
    <jsp:forward page="/index2.jsp" />
</body>
</html>

Index2.jsp

<%@ page language="java" errorPage="/error.jsp" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%
        String name = (String)pageContext.getAttribute("name");
    %>
        name:<%=name %>
</body>
</html>

運行結果如下:

image

使用了服務器端跳轉,但是發現內容并不能取得,證明page范圍的屬性只能在本頁中取得,跳轉到其他頁面之中不能取得。

2、request屬性范圍

request屬性范圍表示在一次服務器跳轉中有效,只要是服務器跳轉,則設置的request屬性可以一直傳遞下去。

例如:

Index.jsp



<%
    request.setAttribute("name","Zender");
%>
<%--使用jsp:forward標簽進行服務器端跳轉--%>
<jsp:forward page="/index2.jsp" />


Index2.jsp



<%
    String name = (String)request.getAttribute("name");
%>
    name:<%=name %>


運行結果如下:

image

修改Index2.jsp代碼如下:



<%
    String name = (String)request.getAttribute("name");
%>
    name:<%=name %>
<a href="/JSP/index3.jsp">鏈接跳轉</a>


Index3.jsp代碼如下:



<%
    String name = (String)request.getAttribute("name");
%>
    name:<%=name %>


使用了超鏈接的方式傳遞的話,則屬性是無法向下繼續傳遞的,一旦跳轉之后,地址欄改變,所以此種跳轉也可以稱為客戶端跳轉。點擊鏈接跳轉結果如下:

image

3、Session屬性范圍

session設置的屬性不管如何跳轉,都可以取得的(session只針對一個用戶)。

例如:

Index.jsp



<%
session.setAttribute("name","Zender");
%>
<%--使用jsp:forward標簽進行服務器端跳轉--%>
<jsp:forward page="/index2.jsp" />


Index2.jsp



<%
    String name = (String)session.getAttribute("name");
%>
    name:<%=name %>
<%--使用超鏈接這種客戶端跳轉--%>
<a href="/JSP/index3.jsp">鏈接跳轉</a>


Index3.jsp



<%
    String name = (String)session.getAttribute("name");
%>
    name:<%=name %>


訪問Index.jsp(服務器端跳轉到index2.jsp):

image

點擊鏈接跳轉(客戶端跳轉到index3.jsp):

image

4、application屬性范圍

application屬性范圍是在服務器上設置的一個屬性,所以一旦設置之后任何用戶都可以瀏覽到此屬性(服務器上設置了過多的application屬性,則會影響到服務器的性能)。

例如:

Index.jsp



<%
application.setAttribute("name","Zender");
%>
<%--使用jsp:forward標簽進行服務器端跳轉--%>
<jsp:forward page="/index2.jsp" />


Index2.jsp

<%
    String name = (String)application.getAttribute("name");
%>
    name:<%=name %>
<%--使用超鏈接這種客戶端跳轉--%>
<a href="/JSP/index3.jsp">鏈接跳轉</a>

Index3.jsp



<%
    String name = (String)application.getAttribute("name");
%>
    name:<%=name %>


訪問Index.jsp(服務器端跳轉到index2.jsp):

image

點擊鏈接跳轉(客戶端跳轉到index3.jsp):

image

重啟web服務器后訪問index2.jsp或者index3.jsp:

image
image

六、JSP標簽

JSP標簽也稱之為Jsp Action(JSP動作)元素,它用于在Jsp頁面中提供業務邏輯功能,避免在JSP頁面中直接編寫java代碼,造成jsp頁面難以維護。

常用標簽有以下三個:

1、<jsp:include>標簽

<jsp:include>標簽用于把另外一個資源的輸出內容插入進當前JSP頁面的輸出內容之中,這種在JSP頁面執行時的引入方式稱之為動態引入。

語法:<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

page 用于指定被引入資源的相對路徑,它也可以通過執行一個表達式來獲得。
flush 指定在插入其他資源的輸出內容時,是否先將當前JSP頁面的已輸出的內容刷新到客戶端。

<jsp:include>標簽與include指令的區別:

<jsp:include>標簽是動態引入, <jsp:include>標簽涉及到的2個JSP頁面會被翻譯成2個servlet,這2個servlet的內容在執行時進行合并。 而include指令是靜態引入,涉及到的2個JSP頁面會被翻譯成一個servlet,其內容是在源文件級別進行合并。

2、<jsp:forward>標簽

<jsp:forward>標簽用于把請求轉發給另外一個資源(服務器跳轉,地址不變)。

語法:<jsp:forward page="relativeURL | <%=expression%>" />

page 用于指定請求轉發到的資源的相對路徑,它也可以通過執行一個表達式來獲得。

3、<jsp:param>標簽

在使用<jsp:include>和<jsp:forward>標簽引入或將請求轉發給其它資源時,可以使用<jsp:param>標簽向這個資源傳遞參數。value屬性用于指定參數值。在<jsp:include>和<jsp:forward>標簽中可以使用多個<jsp:param>標簽來傳遞多個參數。

語法1:

<jsp:include page="relativeURL | <%=expression%>">

<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

</jsp:include>

語法2:

<jsp:forward page="relativeURL | <%=expression%>">

<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

</jsp:forward>
name 用于指定參數名
value 指定參數值

例如:

index.jsp



<%--使用jsp:forward標簽進行服務器端跳轉,--%>
<jsp:forward page="/index2.jsp" >
    <jsp:param value="10086" name="num"/>
    <jsp:param value="10010" name="num2"/>
</jsp:forward>


Index2.jsp

num:<%=request.getParameter("num") %>
<br/>
num2:<%=request.getParameter("num2") %>

運行結果如下:

image
image
image
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容