Cookie-Session-JSP

一.會話技術(shù)

1.1 什么是會話

從瀏覽器和服務(wù)器建立連接開始,一直到瀏覽器關(guān)閉的整個過程就是一次會話

1.2 為什么要使用會話技術(shù)

HTTP是無狀態(tài)協(xié)議,協(xié)議中不能夠存儲數(shù)據(jù); 比如: 不能把登陸狀態(tài)保存在協(xié)議里面;
Request 和 ServletContext 也可以存儲信息, 那么為什么要使用會話, 作用域不同;

1.3 會話技術(shù)的分類

1.3.1 客戶端的會話技術(shù) Cookie

客戶端會話技術(shù), 它是服務(wù)器存放在瀏覽器的一小份數(shù)據(jù), 瀏覽器以后每次訪問該服務(wù)器的時候都會將這小份數(shù)據(jù)攜帶到服務(wù)器;

1.3.2 服務(wù)端的會話技術(shù) Session

服務(wù)端會話技術(shù), 將一次會話信息保存到服務(wù)器;


二.Cookie

2.1 Cookie 的流程

1.瀏覽器A 第一次向服務(wù)端 ServletA 發(fā)起請求,服務(wù)端將此次請求所攜帶的數(shù)據(jù)以 Cookie 的形式響應(yīng)給瀏覽器;
2.瀏覽器A 如果瀏覽器A沒有關(guān)閉, 第二次或更多次向服務(wù)端 ServletB 發(fā)起請求,會將之前的 Cookie 一并發(fā)送給服務(wù)端;
3.服務(wù)端 ServletB 或者其它的Servlet 可以從 Cookie 中取出瀏覽器A 第一次發(fā)起請求時所攜帶的數(shù)據(jù);

2.2 Cookie 的使用

先后訪問 ServletCookie01, ServletCookie02, ServletCookei03

/**
 * Cookie的使用步驟:
 * 1. 創(chuàng)建cookie显晶,存儲鍵值對
 * 2. 設(shè)置cookie
 *    2.1 設(shè)置 cookie 的有效期 (Cookie的默認(rèn)有效期是一次會話)
 *        cookie.setMaxAge(-1); (默認(rèn)是一會話)
 *        cookie.setMaxAge(正整數(shù));
 *        cookie.setMaxAge(0); (刪除cookie)
 *    2.2 設(shè)置 cookie 的有效路徑 (Cookie的默認(rèn)有效路徑是所有服務(wù)器的項目)
 *        setPath(路徑)贷岸,要求路徑需要使用絕對路徑表示,一般我們會設(shè)置為"當(dāng)前項目"
 * 3. 將cookie添加到response中
 *
 * 怎么樣才能刪除瀏覽器中的 cookie:
 * 1. 如果 cookie 的有效期是一次會話,那么關(guān)閉瀏覽器 cookie 就刪除了
 * 2. 如果 cookie 的有效期不是一次會話磷雇,我們需要清除瀏覽器緩存才能刪除 cookie
 * 3. 怎么用代碼刪除 cookie:
 *    使用代碼往客戶端存儲一個同名偿警、同 path 的 cookie,但是有效期為 0
 */
@WebServlet("/01")
public class ServletCookie01 extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // Cookie 存儲中文需要使用 URLEncoder 進(jìn)行編碼
        String strCookie = URLEncoder.encode("一代大神", "UTF-8");
        // 創(chuàng)建 Cookie 對象,存儲鍵值對
        Cookie cookie = new Cookie("username", strCookie);
        // 設(shè)置 cookie 有效期
        cookie.setMaxAge(60*60*24*7);
        // 設(shè)置 cookie 的有效路徑
        // request.getContextPath() 獲取項目的部署路徑
        cookie.setPath(req.getContextPath()+"/02");
        // 將 cookie 添加到 response 中
        resp.addCookie(cookie);
    }
}
@WebServlet("/02")
public class ServletCookie02 extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // 不止一個 cookie 對象 需要遍歷
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            // 通過匹配 cookie 的 name 找到之前存入的 value 值
            if (cookie.getName().equals("username")) {
                //取出 (通過utf-8解碼)
                String decodeStr = URLDecoder.decode(cookie.getValue(), "UTF-8");
                System.out.println("decodeStr= " + decodeStr);
            }
        }
    }
}
@WebServlet("/03")
public class ServletCookie03 extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // 不止一個 cookie 對象 需要遍歷
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            // 通過匹配 cookie 的 name 找到之前存入的 value 值
            if (cookie.getName().equals("username")) {
                //取出 (通過utf-8解碼)
                String decodeStr = URLDecoder.decode(cookie.getValue(), "UTF-8");
                System.out.println("decodeStr= " + decodeStr);
            }
        }
    }
}

2.3 Cookie 的銷毀

  • 默認(rèn)有效期, 會在瀏覽器關(guān)閉時銷毀;

  • 瀏覽器清除緩存;

  • 往瀏覽器存儲一個同名同路徑, 并且時長限制為 0 的Cookie;

    @WebServlet("/03")
    public class ServletCookie03 extends HttpServlet {
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html;charset=UTF-8");
            
            // Cookie 存儲中文需要使用 URLEncoder 進(jìn)行編碼
            String strCookie = URLEncoder.encode("一代大神", "UTF-8");
            // 創(chuàng)建 Cookie 對象,存儲鍵值對
            Cookie cookie = new Cookie("username", strCookie);
            // 設(shè)置 cookie 有效期
            cookie.setMaxAge(0);
            // 設(shè)置 cookie 的有效路徑
            // request.getContextPath() 獲取項目的部署路徑
            cookie.setPath(req.getContextPath()+"/02");
            // 將 cookie 添加到 response 中
            resp.addCookie(cookie);
        }
    }
    

2.4 Cookie 的應(yīng)用場景

  • 記住用戶名

  • 自動登錄

  • 保存電影的播放進(jìn)度

  • 保存上次訪問的時間

    @WebServlet("/lastTime")
    public class ServletRememberLastTime extends HttpServlet {
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html;charset=UTF-8");
    
            // 獲取請求中的 cookie
            String lastTime = null;
            Cookie[] cookies = req.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("lastTime")) {
                        lastTime = cookie.getValue();
                    }
                }
            }
    
            // 獲取當(dāng)前時間
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formatTime = dateFormat.format(new Date());
            if (lastTime == null || lastTime.length() == 0) {
                resp.getWriter().write(formatTime);
            } else {
                lastTime = URLDecoder.decode(lastTime, "UTF-8");
                resp.getWriter().write(lastTime);
            }
    
            // 將獲取到的當(dāng)前時間存入 Cookie
            String encodeStr = URLEncoder.encode(formatTime, "UTF-8");
            Cookie cookie = new Cookie("lastTime", encodeStr);
            resp.addCookie(cookie);
        }
    }
    

三.Session

3.1 Session 的流程

1.瀏覽器A 第一次向服務(wù)端 ServletA 發(fā)起請求,服務(wù)端將此次請求所攜帶的數(shù)據(jù)保存在服務(wù)端的 Session 對象中;
2.瀏覽器A 第二次向服務(wù)端 ServletB 發(fā)起請求;
3.服務(wù)端 ServletB 可以從服務(wù)端的 Session 對象中取出第一次請求時所攜帶的數(shù)據(jù);

3.2 Session 的使用

先訪問 ServletSession01, 再訪問 ServletSession02;

@WebServlet("/ServletSession01")
public class ServletSession01 extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        HttpSession session = req.getSession();
        session.setAttribute("username","二代大神");

    }
}
@WebServlet("/ServletSession02")
public class ServletSession02 extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        Object username = req.getSession().getAttribute("username");
        System.out.println("username = " + username);
    }
}

3.3 Session 的銷毀

  • 默認(rèn)是閑置30分鐘就會銷毀;

  • 服務(wù)器異常關(guān)閉;

    • 如果是正常關(guān)閉服務(wù)器

      目錄查看

      C:\Users\用戶名\.IntelliJIdea2017.2\system\tomcat\_sz61\work\Catalina\localhost

    • Session 的鈍化

      把內(nèi)存中的session序列化保存到硬盤上

    • Session 的活化

      從硬盤上讀取序列化的session到內(nèi)存中形成一個session對象

  • 手動調(diào)用 Session 對象的 invalidate()方法

3.4 Session 的原理

Session 是基于 Cookie的;
1.瀏覽器A 第一次向服務(wù)端 ServletA 發(fā)起請求;
2.然后服務(wù)端第一次調(diào)用 request.getSession();
3.此時服務(wù)端會先從瀏覽器傳送的 Cookie 中尋找 JSESSIONID; 
    如果沒有找到,則會創(chuàng)建一個 Session 對象并生成一個 JSESSIONID 寫到 Cookie 中,然后響應(yīng)給瀏覽器;
    如果找到了JSESSIONID, 則會通過這個 JSESSIONID 去尋找對應(yīng)的 Session 對象; 
    如果這個 JSESSIONID 對應(yīng)的 Session 對象已經(jīng)被銷毀了,則會重復(fù)上述創(chuàng)建過程;
4.如果此次會話正常,那么瀏覽器A 第二次以后向服務(wù)器發(fā)送的請求,服務(wù)端都可以拿到同一個 Session 對象去取出相應(yīng)的數(shù)據(jù); 
瀏覽器關(guān)閉了, session使用不了, 是session銷毀了嗎?
    session 沒有銷毀.  
    session 基于cookie, sessionId 保存到 cookie 里面的, 默認(rèn)情況下 cookie 是會話級別, 瀏覽器關(guān)閉了 cookie 就是消失了,也就是說 sessionId 消失了, 從而找不到對應(yīng)的 session 對象了, 就不能使用了;
    解決:自己獲得 sessionId, 自己寫給瀏覽器設(shè)置 Cookie 的有效時長, 這個 Cookie 的key必須是JSESSIONID

3.5 Session 的應(yīng)用場景

  • 驗證碼存儲
  • 用戶登錄態(tài)的存儲

四.域?qū)ο蟮膶Ρ?/h1>

4.1 Cookie 與 Session的對比

  • Cookie 是保存在瀏覽器上的, 而 Session 是保存在服務(wù)端;
  • Cookie 只能存儲字符串, 并且所帶的字符串中不可以有空格, 如果字符串中帶有中文需要使的 URLEncoder 重新編碼, 新版; Session 可以存儲基本數(shù)據(jù)類型,引用數(shù)據(jù)類型;
  • Cookie 有大小限制, Session原則上沒有;

4.2 Cookie,Session與其它域?qū)ο蟮膶Ρ?/h2>
域?qū)ο?/th> 創(chuàng)建 銷毀 作用范圍 應(yīng)用場景
ServletContext 服務(wù)器啟動 服務(wù)器正常關(guān)閉/項目從服務(wù)器移除 整個項目 記錄網(wǎng)站訪問次數(shù),聊天室
HttpSession 沒有JSESSIONID這個cookie的時候唯笙,調(diào) 用request.getSession()方法 session過期(默認(rèn)閑置30分鐘)螟蒸,或者調(diào)用session對象的 invalidate()方法盒使,或者服務(wù)器異常關(guān)閉 會話(多次請求) 驗證碼校驗, 保存用戶登錄狀態(tài)
Cookie new 出來 與 Cookie 設(shè)置的有效時長有關(guān), 同樣可以設(shè)置刪除Cookie 會話(多次請求) 記住用戶名, 自動登錄, 保存電影的播放進(jìn)度, 保存上次訪問的時間
HttpServletRequest 來了請求 響應(yīng)這個請求(或者請求已經(jīng)接收了) 一次請求 servletA和jsp (servletB)之間數(shù)據(jù)傳遞(轉(zhuǎn)發(fā)的時候存數(shù)據(jù))

五.JSP入門

5.1 什么是JSP

全稱是Java Server Page(Java服務(wù)器頁面),其本質(zhì)是Servlet;
JSP與Servlet一樣,都是SUN公司定義的用于開發(fā)動態(tài)Web資源的技術(shù);
JSP = Html+Java+Jsp(內(nèi)置對象,指令,動作標(biāo)簽等)特有的內(nèi)容

5.2 為什么要使用JSP

為了簡化代碼,Servlet在展示頁面(比如要動態(tài)的向頁面輸入一個表格)的時候,相當(dāng)?shù)姆爆? Sun公司為了解決這個問題,參照Asp開發(fā)了一套動態(tài)網(wǎng)頁技術(shù)Jsp;

5.3 JSP的三種Java腳本

通過 JSP 的 Java 腳本, 可以在里面寫 Java 代碼;

類型 翻譯成Servlet對應(yīng)的部分 注意
<%...%>:Java程序片段 翻譯成Service()方法里面的內(nèi)容, 局部的
<%=...%>:輸出表達(dá)式 翻譯成Service()方法里面的內(nèi)容,相當(dāng)于調(diào)用out.print() 輸出表達(dá)式不能以;結(jié)尾
<%!...%>:聲明成員變量(肯定不用) 翻譯成Servlet類里面的內(nèi)容
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP學(xué)習(xí)</title>
</head>
<body>
<%--
1.Jsp的注釋
    1.1 Html的注釋
    1.2 Java的注釋
    1.3 Jsp自己的注釋

2.能過腳本在JSP中編寫Java代碼
    2.1 <%%>角本,這種角本在 Jsp 解析之后,運行的 service() 方法中;
    2.2 <%=%>角本,這種用于往瀏覽器頁面輸出一個java變量,其實就是調(diào)用輸出流對象的print方法向瀏覽器輸出"="后面的數(shù)據(jù);
    2.3 <%!%>角本,這種角本用于定義成員變量和成員函數(shù),這種腳本在翻譯成java文件之后,是運行在 service() 方法外面的;
--%>
<%
    int num = 0;
    String username = "二代大神<br>";
    sayHello();
    // jsp的內(nèi)置對象
    response.getWriter().write("你今天快樂嗎?<br>");
%>
username = <%=username%>
password = <%=password%>
<%!
    public String password = "三代大神<br>";
    public void sayHello() {
        System.out.println("你今天快樂嗎?");
    }
%>
</body>
</html>

5.4 JSP的執(zhí)行原理

JSP角本會被翻譯(通過默認(rèn)的JspServlet,JSP引擎)成Servlet(.Java文件),并編譯成.class文件;
執(zhí)行流程:
    1.第一次訪問.jsp文件是時候,服務(wù)器收到請求,JspServlet會去查找這個文件;
    2.然后,服務(wù)器會將這個.jsp文件轉(zhuǎn)換成.java文件;
    3.編譯.java文件,生成.class文件;
    4.服務(wù)器運行.class文件,生成動態(tài)內(nèi)容;
    5.最后服務(wù)器將這些生成的動態(tài)內(nèi)容,響應(yīng)給瀏覽器;
<%%>  翻譯成了service()方法里面的局部內(nèi)容;
<%=%> 翻譯成了service()方法里面的 out.print();
<%!%> 翻譯成了servlet類里面的全局內(nèi)容;

六.EL表達(dá)式

6.1 什么是EL表達(dá)式

全稱是 Expression Language: 表達(dá)式語言, JSP 2.0之后內(nèi)置在 JSP 里面;

其語法格式為 ${el表達(dá)式};

6.2 為什么要使用EL表達(dá)式

為了使 JSP 寫起來更加簡單, 取值 (取的域?qū)ο罄锩娲娴闹? 更加簡單(代替腳本 <% %>); 目的肯定是為了簡化代碼, 但是感覺上并沒有簡化多少;

1.獲取數(shù)據(jù). 獲取的是 域( request,session, ServletContext ) 對象中存儲的數(shù)據(jù);

2.EL執(zhí)行運算;

6.3 EL表達(dá)式的使用

6.3.1 獲了簡單數(shù)據(jù)類型的數(shù)據(jù)

語法格式為:
    ${applicationScope.key}
    ${sessionScope.key}
    ${requestScope.key}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Jsp_EL表達(dá)式學(xué)習(xí)</title>
</head>
<body>
    <%
        // application 對象就是 ServletContext 對象
        application.setAttribute("username", "一代大神");
        session.setAttribute("username", "二代大神");
        request.setAttribute("username", "三代大神");
    %>
    <%-- 顯示 application 中獲取到的username= ${applicationScope.username}<br> --%>
    <%-- 顯示 session 中獲取到的username= ${sessionScope.username}<br> --%>
    <%-- 顯示 request 中獲取到的username= ${requestScope.username} --%>
    <%-- 獲取域?qū)ο笾写娴闹悼梢詫慿ey值,如果key值相同的話,則會取范圍最小的那一個,
         但是一般key值不會相同;
    --%>
    顯示 application 中獲取到的username= ${username}<br>
    顯示 session 中獲取到的username= ${username}<br>
    顯示 request 中獲取到的username= ${username}
</body>
</html>

6.3.2 獲取復(fù)雜類型的數(shù)據(jù)

獲取數(shù)組
    其語法格式為: ${對象名[index]}
獲取list
    其語法格式為: ${對象名[index]}
獲取map
    其語法格式為: ${對象名.key}或者${對象名."key"}
獲取bean
    其語法格式為: ${對象名.key}或者${對象名."key"}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL獲取復(fù)雜類型的數(shù)據(jù)</title>
</head>
<body>
    <%
        String[] elStrings = {"一代大神", "一代二神", "一代三神"};
        request.setAttribute("elStrings", elStrings);

        ArrayList list = new ArrayList();
        list.add("一代四神");
        list.add("一代五神");
        list.add("一代六神");
        request.setAttribute("list", list);

        HashMap map = new HashMap();
        map.put("一代七神", "一代七神");
        map.put("一代八神", "一代八神");
        map.put("一代九神", "一代九神");
        request.setAttribute("map", map);
    
        User user = new User("shaShen","shaShen");
        request.setAttribute("user",user);
    %>
    <%-- 在EL表達(dá)式中,只要是根據(jù)下標(biāo)取數(shù)據(jù)都可以寫成 [index] --%>
    取出存放在request對象中數(shù)組的第2個元素 = ${elStrings[1]}
    <br>
    取出存放在request對象中l(wèi)ist的第2個元素 = ${list[1]}
    <br>

    <%-- 在el表達(dá)式中,只要是根據(jù)對應(yīng)的屬性的get方法去獲取數(shù)據(jù)都可以寫成 .key 或者 ["key"]
        但是好像不能有特殊字符像"_"或者"-"這樣的都不可以,可以有中文;
    --%>
    取出存放在request對象中map中的key為"一代八神"的元素 =${map.一代八神}
    <br>
    取出存放在request對象中map中的key為"一代九神"的元素  =${map["一代九神"]}
    <br>
    取出存放在request對象中user對象的username值 = ${user.username}
    <br>
    取出存放在request對象中user對象的password值 = ${user["password"]}
</body>
</html>

6.3.3 EL執(zhí)行運算

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL執(zhí)行運算</title>
</head>
<body>
<%
    //el表達(dá)式中的empty可以判斷一個字符串是否為空字符串七嫌,一個對象是否為null少办,一個集合的長度是否為0
    ArrayList<String> list = new ArrayList<String>();
    list.add("張三豐");
    request.setAttribute("list", list);

    request.setAttribute("msg", "requestValue");

    User user = new User();
    request.setAttribute("u", user);
%>
判斷域?qū)ο笾械膌ist集合的長度是否為0: ${empty list}<br>
判斷域?qū)ο笾械膍sg字符串是否為空字符串: ${empty msg}<br>
判斷域?qū)ο笾械膗ser是否為null : ${empty u}<br>
判斷域?qū)ο笾械膍sg的值是否等于requestValue : ${msg.equals("requestValue")}<br>
判斷域?qū)ο笾械膍sg的值是否等于requestValue : ${msg==("requestValue")}<br>
</body>
</html>

6.3.4 EL獲取 Cookie 中的數(shù)據(jù)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL執(zhí)行運算</title>
</head>
<body>
<%-- Jsp里面是內(nèi)置的Session對象,則可以通過Cookie對象獲取JESSIONID的值 --%>
<%
    Cookie[] cookies = request.getCookies();
    String sessionID = null;
    for (Cookie cookie : cookies) {
        if (cookie.getName().equals("JSESSIONID")) {
            sessionID = cookie.getValue();
        }
    }
%>
使用原始方式獲取Cookie中的JSESSIONID值為<%=sessionID%>
<br>
<%--
    ${cookie}表示獲取這次請求中的所有cookie對象
    ${cookie.JSESSIONID}表示獲取名為"JSESSIONID"的cookie對象
    ${cookie.JSESSIONID.value}表示獲取名為"JSESSIONID"的cookie對象的value
--%>
使用EL方式獲取Cookie中的JSESSIONID值為${cookie.JSESSIONID.value}
</body>
</html>

七.JSTL標(biāo)簽庫

7.1 什么是JSTL標(biāo)簽庫

JSTL全稱JSP Standard Tab Library, JSP標(biāo)準(zhǔn)標(biāo)簽庫是一個不斷完善的開放源代碼的JSP標(biāo)簽庫; 通過這些標(biāo)簽庫可以簡化在JSP頁面上操作數(shù)據(jù)的代碼, 比如遍歷數(shù)據(jù), 判斷數(shù)據(jù)等;

JSTL不是內(nèi)置的, 需要導(dǎo)包, 并且添加標(biāo)答庫類別:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

7.2 JSTL標(biāo)簽庫的使用

if標(biāo)簽
    <c:if text="${}"></c:if>
choose 標(biāo)簽
    <c:choose>
        <c:when test="${}"></c:when>
        <c:when test="${}"></c:when>
        <c:otherwise></c:otherwise>
    </c:choose>
forEach 標(biāo)簽
    1.begin屬性:從哪個下標(biāo)開始遍歷,如果不寫默認(rèn)是從0開始
    2.end屬性:到哪個下標(biāo)結(jié)束遍歷,如果不寫默認(rèn)是到集合/數(shù)據(jù)的最后一個元素
    3.step屬性:表示遍歷時候的步長,默認(rèn)步長是1
    4.var屬性:表示將遍歷的結(jié)果存放進(jìn)域?qū)ο髸r候的key  
    5.item屬性:指定要遍歷的對象
    <c:forEach>
    </c:forEach>
forEach 標(biāo)簽的 varStatus 屬性
    狀態(tài)屬性:
        1.index 下標(biāo)
        2.count 計數(shù)
        3.current 當(dāng)前元素的值
        4.first 是否是第一個元素
        5.last 是否是最后一個元素
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP標(biāo)簽學(xué)習(xí)</title>
</head>
<body>
<%
    // 往標(biāo)簽中存入age
    request.setAttribute("age", 19);
    request.setAttribute("course", "PHP");

    ArrayList list = new ArrayList();
    list.add("張三");
    list.add("李四");
    list.add("王五");
    list.add("趙六");
    list.add("田七");
    request.setAttribute("list", list);
%>
<%-- 判斷age是否大于等于18,如果大于等于18則輸出:已成年抄瑟,否則輸出未成年 --%>
<%-- 第一種方式:三目運算符--%>
${age>=18?"1.已成年":"未成年"}
<br>
<%-- 第二種方式:if標(biāo)簽 --%>
<c:if test="${age>=18}">
    2.已成年
</c:if>
<c:if test="${age<18}">
    未成年
</c:if>
<br>

<%-- choose標(biāo)簽 --%>
<c:choose>
    <c:when test="${course=='JAVA'}">
        學(xué)習(xí)Java
    </c:when>
    <c:when test="${course=='C'}">
        學(xué)習(xí)C
    </c:when>
    <c:when test="${course=='PHP'}">
        學(xué)習(xí)拍黃片
    </c:when>
    <c:otherwise>
        學(xué)習(xí),學(xué)個屁!
    </c:otherwise>
</c:choose>
<br>
<%-- foreach標(biāo)簽 --%>
<%-- 輸出 0-9 --%>
<c:forEach begin="0" end="9" var="i">
    ${i}<br>
</c:forEach>

<%-- 輸出 list 中的數(shù)據(jù) --%>
<c:forEach items="${list}" var="username">
    ${username}<br>
</c:forEach>

<%-- 以表格的形式輸入 list 中的數(shù)據(jù),測試 varStatus 狀態(tài)屬性--%>
<table border="1px" cellspacing="0" cellpadding="20">
    <tr>
        <th>begin 開始</th>
        <th>end 結(jié)否</th>
        <th>step 自增或自減數(shù)</th>
        <th>count 第幾個元素</th>
        <th>current 當(dāng)前元素</th>
        <th>first 是否是首位元素</th>
        <th>last 是否是末位元素</th>
        <th>index 當(dāng)前元素下標(biāo)</th>
    </tr>
    <c:forEach items="${list}" varStatus="vars">
        <tr>
            <td>${vars.begin}</td>
            <td>${vars.end}</td>
            <td>${vars.step}</td>
            <td>${vars.count}</td>
            <td>${vars.current}</td>
            <td>${vars.first}</td>
            <td>${vars.last}</td>
            <td>${vars.index}</td>
        </tr>
    </c:forEach>
</table>
</body>
</html>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凡泣,一起剝皮案震驚了整個濱河市枉疼,隨后出現(xiàn)的幾起案子皮假,更是在濱河造成了極大的恐慌,老刑警劉巖骂维,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惹资,死亡現(xiàn)場離奇詭異,居然都是意外死亡航闺,警方通過查閱死者的電腦和手機(jī)褪测,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潦刃,“玉大人侮措,你說我怎么就攤上這事」愿埽” “怎么了买置?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵竭沫,是天一觀的道長。 經(jīng)常有香客問我,道長伐弹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任柑爸,我火速辦了婚禮让腹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘列赎。我一直安慰自己宏悦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布包吝。 她就那樣靜靜地躺著肛根,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漏策。 梳的紋絲不亂的頭發(fā)上派哲,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音掺喻,去河邊找鬼芭届。 笑死储矩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的褂乍。 我是一名探鬼主播持隧,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逃片!你這毒婦竟也來了屡拨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤褥实,失蹤者是張志新(化名)和其女友劉穎呀狼,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體损离,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡哥艇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了僻澎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片貌踏。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖窟勃,靈堂內(nèi)的尸體忽然破棺而出祖乳,到底是詐尸還是另有隱情,我是刑警寧澤秉氧,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布眷昆,位于F島的核電站,受9級特大地震影響谬运,放射性物質(zhì)發(fā)生泄漏隙赁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一梆暖、第九天 我趴在偏房一處隱蔽的房頂上張望伞访。 院中可真熱鬧,春花似錦轰驳、人聲如沸厚掷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冒黑。三九已至,卻和暖如春勤哗,著一層夾襖步出監(jiān)牢的瞬間抡爹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工芒划, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留冬竟,地道東北人欧穴。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像泵殴,于是被迫代替她去往敵國和親涮帘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354