天天看點

Java學習路線-51:JSP 快速入門11-JSP 快速入門第 1 章 : JSP 入門第 2 章 : Cookie 處理第 3 章 : HttpSession第 4 章 : 驗證碼第 5 章 : JSP 指令第 6 章 : JSP 動作标簽

11-JSP 快速入門

第 1 章 : JSP 入門

課時 1 JSP 入門

Java Server Pages

jsp 本質就是 Servlet

jsp:在原有 html 基礎上添加 java 腳本

分工:

jsp 顯示資料

servlet 處理資料

jsp -> servlet -> jsp      

jsp 組成:

1、html + java 腳本 + jsp 标簽(指令)

2、9 個内置對象:

request
response
session
application
pageContext
config
out
page
exception      

3、3 種腳本

<% %> Java代碼片段,多條代碼
<%=%> Java表達式,一條代碼
<%!%> 聲明成員      

課時 2 JSP 中 Java 腳本的示範

html 中的 base 标簽

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

<%
// java語句
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +  request.getContextPath();
// http://localhost:8080/demo
%>

<%=basePath%>

<%
// 等價于
out.print(basePath);
%>

<br/>

<%!
// 成員變量
int a = 5;

// 成員方法
public void getValue(){
    System.out.print("hi");
}
%>

<% int a = 10; // 局部變量 %>

通路局部變量:
<%=a%>

通路成員變量:
<%=this.a%>

<%
// 調用成員方法
getValue();
%>

清單循環
<ol>
<% for(int i=0; i< 10; i++){ %>
    <li><%=i%></li>
<% } %>
</ol>      

課時 3 JSP 和 Servlet 分工的案例

電腦示例

  1. 擷取表單資料 form.jsp
  2. 把字元串轉換成 int 類型
  3. 進行加法運算得到結果
  4. 儲存資料結果到 request 中
  5. 轉發到 result.jsp

處理流程

form.jsp -> servlet ->  result.jsp      

代碼檔案

form.jsp

<form action="calculate" method="post">
  <input type="text" name="num1" />
  <input type="text" name="num2" />
  <input type="submit" />
</form>      

CalculateServlet.java

package com.pengshiyu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CalculateServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 擷取參數
        String s1 = request.getParameter("num1");
        String s2 = request.getParameter("num2");

        // 類型轉換
        int num1 = Integer.parseInt(s1);
        int num2 = Integer.parseInt(s2);

        // 求和
        int result = num1 + num2;

        // 指派
        request.setAttribute("result", result);

        // 轉發
        request.getRequestDispatcher("/result.jsp").forward(request, response);
    }
}
      

result.jsp

<%=request.getAttribute("result")%>      

課時 4 JSP 的原理

jsp 是一個特殊的 servlet

第一次通路 jsp 頁面時,伺服器會把 jsp 編譯成 java 檔案,一個 servlet 類

再把.java 檔案編譯成.class 檔案

建立該類對象

最後調用它的 service()方法

第二次通路同一個 jsp 頁面時,直接調用 service()方法

流程圖

第一次通路:
用戶端 -> 伺服器 -> jsp -> java -> class -> 建立Servlet對象 -> 調用service()方法

第二次之後通路:
用戶端 -> 伺服器 -> jsp -> 調用service()方法      

jsp 編譯為 java 類

jsp                 java類
===============================================
頭                          定義9個内置對象
                            為9個内置對象指派
===============================================

體
    html                   out.write()
    <% %>                  原樣搬運
    <%=%>                  out.print()
    <%!%>                  聲明成員
    <%-- --%>              注釋不做翻譯
===============================================
尾                         做異常處理
      

課時 5 JSP 中的注釋

<!-- -->   html注釋
<%-- --%>  jsp注釋,不會輸出到html檔案中      

第 2 章 : Cookie 處理

課時 6 Cookie 入門

Cookie 是 http 協定

由伺服器建立儲存到用戶端浏覽器的一個鍵值對

伺服器響應頭

Set-Cookie: key1=value1; key2=valu2      

用戶端浏覽器下次請求時會帶上 Cookie

用戶端請求頭

Cookie: key1=value1; key2=valu2      

規定:

  1. 1 個 Cookie 最大 4kb
  2. 一個伺服器最多給一個浏覽器 20 個 cookie
  3. 一個浏覽器最多儲存 300 個 cookie

用途:

伺服器跟蹤用戶端狀态

購物車

JavaWeb 中使用:

(1)原始方法
response發送Set-Cookie響應頭
request擷取Cookie請求頭

(2)便捷方法
response.addCookie()
request.getCookies()      

示例

setCookie.jsp

<h2>設定Cookie</h2>
<%
Cookie cookie = new Cookie("key", "value");
response.addCookie(cookie);
%>
      

getCookie.jsp

<h2>擷取Cookie</h2>
<%
Cookie[] cookies = request.getCookies();

if(cookies != null){
    for(Cookie c: cookies){
        out.print(c.getName() + ": "+ c.getValue());
    }
}
%>      

課時 8 Cookie 的路徑

path 設定需要歸還的 cookie 作用域

預設值為目前路徑的父級目錄

eg:
cookie.setPath('/')

eg:
cookieA /demo
cookieB /demo/jsp/
cookieC /demo/jsp/html/

/demo/index.jsp -> cookieA
/demo/jsp/index.jsp -> cookieA、cookieB
/demo/jsp/html/index.jsp -> cookieA、cookieB、cookieC      

課時 9 Cookie 的域

domain 指定共享域名

eg:
cookie.setDomain('.baidu.com')
cookie.setPath('/')
共享:www.baidu.com、zhidao.baidu.com      

第 3 章 : HttpSession

課時 10 HttpSession 入門

HttpSession 用于會話跟蹤,儲存在伺服器端

1、Servlet 三大域對象:

request

session

application

2、HttpSession 底層依賴:

Cookie 或是 Url 重寫

3、會話範圍

使用者首次通路伺服器開始,到該使用者關閉浏覽器結束

4、Servlet 中擷取 session

HttpSession = request.getSession()      

5、jsp 中的 session 是内置對象,可以直接使用

<%
void session.setAttribute(String name, String value);
Object session.getAttribute(String name);
void session.getAttribute(String name);
%>      

課時 11-12 HttpSession 第一例

建立和擷取 session

setSession.jsp 建立 session

<h2>設定Session</h2>
<%
session.setAttribute("name", "Tom");
%>      

getSession.jsp 擷取 session

<h2>擷取Session</h2>
<%=session.getAttribute("name")%>      

課時 13 HttpSession 第二例

登入

思路

login.jsp
-> LoginServlet 登入失敗跳轉回 login.jsp
-> admin.jsp    未登入跳轉回 login.jsp
      

使用 session 關閉浏覽器後就消失

可以使用 cookie 設定儲存時長,持久化到浏覽器中

login.jsp

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

<%
// 如果有msg就顯示
String msg = (String)session.getAttribute("msg");
if(msg == null){
    msg = "";
}
%>

<h2>登入</h2>

<div style="color: red"><%=msg%></div>

<%
  // 清空session中的msg
  session.removeAttribute("msg");
%>

<form action="/demo/login" method="post">
    <input type="text" name="username"><br/>
    <input type="text" name="password"><br/>
    <input type="submit">
</form>      

LoginServlet.java

package com.pengshiyu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        HttpSession session = request.getSession();

        if ("admin".equals(username) && "123456".equals(password)) {
            session.setAttribute("username", username);

            // 添加Cookie
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24); // 儲存一天
            response.addCookie(cookie);

            response.sendRedirect("session/admin.jsp");
        } else {
            session.setAttribute("msg", "賬号或密碼不正确");
            response.sendRedirect("session/login.jsp");
        }
    }
}      

admin.jsp

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

<%
// 從session中擷取
// String username =(String)session.getAttribute("username");

// 從cookie中擷取
String username = null;
Cookie[] cookies = request.getCookies();
for (Cookie c :cookies){
    if(c.getName().equals("username")){
        username = c.getValue();
        break;
    }
}

if(username == null){
    request.getSession().setAttribute("msg", "使用者未登入");
    response.sendRedirect("login.jsp");
}
%>

<h2>歡迎<%=username%></h2>
      

課時 14 HttpSession 原理

sessionId 儲存到 cookie 中

request.getSession(false) // 不會建立sessionId
request.getSession(true)  // 會建立sessionId
request.getSession()      // 會建立sessionId      

課時 15 配置 session 最大不活動時間

public interface HttpSession {
    long getCreationTime();

    String getId();  // 擷取sessionId

    long getLastAccessedTime();

    ServletContext getServletContext();

    // 設定最大不活動時間,預設30分鐘
    void setMaxInactiveInterval(int var1);

    int getMaxInactiveInterval();

    // 讓session失效
    void invalidate();

    // 檢視是否為新的,判斷用戶端第一次請求
    boolean isNew();


    Enumeration<String> getAttributeNames();
    Object getAttribute(String var1);
    void setAttribute(String var1, Object var2);
    void removeAttribute(String var1);

}      

web.xml 中配置 session 最大不活動時間

<session-config>
    <!-- 機關:分鐘 -->
    <session-timeout>30</session-timeout>
</session-config>      

課時 16 session 之 url 重寫

如果浏覽器的 cookie 被禁用了,可以将 sessionId 在 url 參數中傳遞

// 如果cookie中沒有會加到url上
response.encodeURL()      

第 4 章 : 驗證碼

課時 17 生成圖檔(VerfiyCode 類)

package util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;

public class ImageUtil {
    public static void main(String[] args) throws IOException {
        // 建立圖檔緩沖區
        BufferedImage bi = new BufferedImage(50, 50, BufferedImage.TYPE_3BYTE_BGR);
        // 得到繪制環境
        Graphics2D g = (Graphics2D) bi.getGraphics();
        // 設定白色
        g.setColor(Color.WHITE);
        // 繪制矩形,相當于繪制背景色
        g.fillRect(0, 0, 50, 50);
        // 設定紅色
        g.setColor(Color.RED);
        // 寫字
        g.drawString("hello", 2, 35);
        // 儲存輸出
        ImageIO.write(bi, "JPEG", new FileOutputStream("1.jpg"));
    }
}
      

結合登入驗證的完整代碼

login.jsp(VerifyCodeServlet) -> LoginServlet -> admin.jsp      
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%
String msg = (String)session.getAttribute("msg");
if(msg == null){
    msg = "";
}
%>

<h2>登入</h2>

<div style="color: red"><%=msg%></div>

<%
  // 清空session
  session.removeAttribute("msg");
%>

<form action="/demo/login" method="post">
    使用者名:<input type="text" name="username"><br/>
    密碼:<input type="text" name="password"><br/>
    驗證碼:<input type="text" name="verify_code">
    <img src="/demo/code" id="code">  <a href="javascript:changeImage()">換一張</a>
    <br/>
    <input type="submit">
</form>

<script>
function changeImage(){
    let code = document.getElementById("code");
    code.src = "/demo/code?" + new Date().getTime();
}
</script>      
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%
// 從session中擷取
// String username =(String)session.getAttribute("username");

// 從cookie中擷取
String username = null;
Cookie[] cookies = request.getCookies();
if(cookies != null){
    for (Cookie c :cookies){
        if(c.getName().equals("username")){
            username = c.getValue();
            break;
        }
    }
}
if(username == null){
    request.getSession().setAttribute("msg", "使用者未登入");
    response.sendRedirect("login.jsp");
}
%>

<h2>歡迎<%=username%></h2>
      
package com.pengshiyu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String verifyCode = request.getParameter("verify_code");

        HttpSession session = request.getSession();
        String code = (String) session.getAttribute("code");

        // 驗證碼校驗
        if(!code.equalsIgnoreCase(verifyCode)){
            session.setAttribute("msg", "驗證碼不正确");
            response.sendRedirect("session/login.jsp");
            return;
        }

        if ("admin".equals(username) && "123456".equals(password)) {

            session.setAttribute("username", username);

            // 添加Cookie
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24); // 儲存一天
            response.addCookie(cookie);

            response.sendRedirect("session/admin.jsp");
        } else {
            session.setAttribute("msg", "賬号或密碼不正确");
            response.sendRedirect("session/login.jsp");
        }
    }
}      

VerifyCodeServlet.java

package com.pengshiyu.servlet;

import util.ImageUtil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class VerifyCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String code = ImageUtil.getVerifyCode(4);
        request.getSession().setAttribute("code", code);
        ImageUtil.writeImage(code, response.getOutputStream());
    }
}
      

ImageUtil.java

package util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

public class ImageUtil {
    public static void writeImage(String text, OutputStream output) throws IOException {
        // 建立圖檔緩沖區
        BufferedImage bi = new BufferedImage(50, 20, BufferedImage.TYPE_3BYTE_BGR);
        // 得到繪制環境
        Graphics2D g = (Graphics2D) bi.getGraphics();
        // 設定白色
        g.setColor(Color.WHITE);
        // 繪制矩形,相當于繪制背景色
        g.fillRect(0, 0, 50, 20);
        // 設定紅色
        g.setColor(Color.RED);
        // 寫字
        g.drawString(text, 8, 16);
        // 儲存輸出
        ImageIO.write(bi, "JPEG", output);
    }

    public static String getVerifyCode(int length){
        String code  = "1234567890";
        StringBuilder sb = new StringBuilder();

        Random random = new Random();
        for(int i=0; i < length; i ++){
            int index = random.nextInt(code.length());
            sb.append(code.substring(index, index+1));
        }
        return sb.toString();

    }
    public static void main(String[] args) throws IOException {
        ImageUtil.writeImage(ImageUtil.getVerifyCode(4), new FileOutputStream("1.jpg"));
    }
}
      

第 5 章 : JSP 指令

課時 19 page 指令

page

  1. include 靜态包含
  2. taglib 導入标簽庫

指令格式

<%@指令名 attr1="" attr2="" %>      

一般放在檔案最上方,可以有多個

<%@page
language="java"
import="java.util.*,java.net.*"
pageEncoding="UTF-8"
contentType="text/html; charset=utf-8"
errorPage="errorPage.jsp"
%>      

pageEncoding 指定頁面編碼

contentType 響應頭

如果兩個參數隻有一個,那麼預設為設定的那個

如果兩個參數都沒有設定,那麼預設為 iso

import 導包,可以出現多次

errorPage 頁面出錯跳轉

isErrorPage=“true” 是否為處理錯誤的頁面,會設定狀态碼為 500,可以使用 exception

eg:

exception.printStackTrace(response.getWriter());      

web.xml 配置錯誤頁面

<error-page>
    <error-code>404</error-code>
    <location>/error404.jsp</location>
</error-page>

<error-page>
    <error-code>500</error-code>
    <location>/error500.jsp</location>
</error-page>

<error-page>
    <excepiton-type>java.lang.RuntimeException</excepiton-type>
    <location>/error.jsp</location>
</error-page>      

autoFlush 指定緩沖區滿時是否自動重新整理

buffer 緩沖區大小,預設 8kb

isELIgnored 是否忽略 EL 表達式,預設為 false,不忽略

基本不用

language 指定目前 jsp 編譯後的語言類型,預設為 java

extends 指定目前頁面生成 Servlet 的父類

isThreadSafe 是否支援并發通路 預設為 false,為 true 已過時

info 資訊

session 是否支援 session,如果為 false,就沒有 session 對象

課時 20 pageContext 對象

9 大内置對象

  1. out JspWriter response.getWriter() 發送文本資料
  2. config ServletConfig this.ServletConfig
  3. page this,目前 jsp 對象
  4. pageContext 頁面上下文對象 一個頂 9 個
  5. exception 隻有在錯誤頁面中使用
  6. request HttpServletRequest
  7. respone HttpServletResponse
  8. application ServletContext
  9. session HttpSession

Servlet 中有大個域對象,

JSP 中有四個域對象:

  1. ServletContext 整個應用程式
  2. session 整個會話,一個會話中隻有一個使用者
  3. request 一個請求鍊
  4. pageContext 一個 jsp 頁面,目前頁面标簽之間共享資料
// 代理其他域對象
pageContext.setAttribute("key", "value", PageContext.SESSION_SCOPE)

// 全域查找,從小到大page、request、response、application
pageContext.findAttribute("key");

// 擷取其他内置對象
      

課時 21 include 和 taglib 指令

1、include 靜态包含 jsp 編譯成 java 檔案時完成

<%@include file="demo.jsp" %>      

2、tablib 導入标簽庫

<%@taglib prefix="s" uri="/tags" %>
<s:text>      

prefix 指定标簽庫字首

uri 指定标簽庫位置

第 6 章 : JSP 動作标簽

課時 22 JSP 動作标簽

  1. 轉發 RequestDispatcher.forword
  2. 包含 RequestDispatcher.include
  3. 傳遞參數

a.jsp 動态包含 b.jsp,并傳遞參數

<jsp:forward page="b.jsp">
    <jsp:param name="key1" value="value1"></jsp:param>
    <jsp:param name="key2" value="value2"></jsp:param>
</jsp:forward>      

b.jsp

<%=request.getParameter("key1")%>
<%=request.getParameter("key2")%>      

課時 23 JSP 在 web.xml 中也可以配置

開發自動重新開機

tomcat/conf/context.xml

<Context reloadable="true">
</Context>