Java之JavaWeb

JavaWeb

基本概念

web開發:

  • web ---- 網頁
  • 靜態web
    • html css 提供給所有人看的 數據始終不會發生變化
  • 動態web
    • 技術棧 servlet/jsp asp php
  • java中動態web資源開發技術統稱爲javaWeb

靜態web

服務器是一種被動的操作,用來處理用戶的一些請求和給用戶一些響應信息

web服務器:
IIS windows自帶
tomcat

Tomcat

啓動關閉 bin/startup.sh shutdown.sh

HTTP:
百度:

Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 36.152.44.96:443

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
  1. 請求行
    • 請求方式:GET POST HEAD DELETE
      • get:請求能夠攜帶的參數比較少,大小有限制,會在url地址欄顯示數據內容,不安全但是高效
      • post:請求能夠攜帶的參數無限制,大小沒有限制,不會在url地址顯示數據內容,安全,但不高效
  2. 消息頭
Accept: 告訴瀏覽器 支持的數據類型
Accept-Encoding: 支持哪種編碼
Accept-Language: 語言環境
Cache-Control: 緩存控制
Connection: 告訴瀏覽器 請求完成是斷開還是保持連接

HTTP響應
200 請求響應成功
3xx 請求重定向
4xx 找不到資源 404
5xx 服務器代碼錯誤 500 502網關錯誤

常見面試題
當瀏覽器地址欄輸入地址並回車的一瞬間到頁面能夠展示回來,經歷了什麼

Maven項目架構管理工具

阿里雲鏡像加速
setting.xml

pom.xml
jar:java應用
war:javaweb應用
properties 配置
build 項目構建用的東西

Servlet

什麼是Servlet
  • Servlet是開發動態web的一門技術
  • Servlet就是一個接口,Servlet只需要編寫一個類實現Servlet,把開發好的java類部署到web服務器中
helloServlet

Servelt接口有兩個默認的實現類 HttpServlet

  1. 構建一個Maven項目,刪掉裏面的src目錄,以後在這個項目裏建立moudel,這個空的工程就是maven主工程
  2. 關於Maven父子工程的理解:
    父項目中會有
    <modules>
        <module>servlet-01</module>
    </modules>
    

父項目中的java子項目可以直接使用

  1. Maven環境優化
    1. 修改web.xml爲最新的
    2. 將maven結構搭建完整
  2. 編寫servlet ,實現Servlet,或者繼承HttpServlet
public class HelloServlet extends HttpServlet {

    //由於get或者post只是請求實現的不同的方式 可以相互調用 業務邏輯都一樣
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.print("Hello,Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  1. 編寫Servlet的映射
    爲什麼需要映射:我們寫的是Java程序,但是需要通過瀏覽器訪問,而瀏覽器需要連接web服務器,所以我們需要在web服務中註冊我們寫的Servlet,還需要給一個瀏覽器能訪問的路徑
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1"
         metadata-complete="true">

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.wang.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
</web-app>
  1. 配置Tomcat
    注意:配置項目發佈的路徑就可以了
  2. 啓動測試
Servlet原理

Servlet是由Web服務器調用,web服務在收到瀏覽器請求之後會:
在這裏插入圖片描述

Mapping問題
  1. 一個Servlet可以指定一個映射路徑
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
  1. 一個Servlet可以指定多個映射路徑
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet1</url-pattern>
    </servlet-mapping>
  1. 一個Servlet可以指定通用映射路徑
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet/*</url-pattern>
    </servlet-mapping>
  1. 默認請求路徑
	可以替換掉默認首頁
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
  1. 指定一些後綴或者前綴等等
	可以自定義後綴實現請求映射
	注意:*前面不能加項目映射的路徑
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  1. 優先級問題
    指定了固有的映射優先級最高,找不到就會找默認請求路徑
	默認請求路徑是ErrorServlet,當訪問/helloServlet的時候,頁面跳轉HelloServlet,但是其它時候就跳轉ErrorServlet
	<servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.wang.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>ErrorServlet</servlet-name>
        <servlet-class>com.wang.servlet.ErrorServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>ErrorServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
ServletContext

web容器在啓動的時候,他會爲每個web程序都創建一個對應的ServletContext對象,它代表了當前的web應用

  • 共享數據
    • 在這個Servlet中保存的數據可以在其它Servlet中使用
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Hello");
//        this.getInitParameter(); 初始化參數
//        this.getServletConfig(); Servlet配置
//        this.getServletContext(); Servlet上下文
        ServletContext context = this.getServletContext();
        String username = "username";
        context.setAttribute("username", username); //將一個數據保存在ServletCOntext中 kv對
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        // HelloServlet中的username可以在GetServelt中獲取到(需要先加載HelloServlet)
        String username = (String) context.getAttribute("username");
        System.out.println(this.getClass().getName() + ":" + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    <servlet>
        <servlet-name>Hello</servlet-name>
        <servlet-class>com.wang.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>GetContext</servlet-name>
        <servlet-class>com.wang.servlet.GetServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>GetContext</servlet-name>
        <url-pattern>/getContext</url-pattern>
    </servlet-mapping>

獲取初始化參數

    <!--    配置一些web應用初始化參數-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://aliyun:3306/mybatis</param-value>
    </context-param>
    <servlet>
        <servlet-name>ServletDemo03</servlet-name>
        <servlet-class>com.wang.servlet.ServletDemo03</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo03</servlet-name>
        <url-pattern>/servletDemo03</url-pattern>
    </servlet-mapping>
public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        System.out.println(url); //jdbc:mysql://aliyun:3306/mybatis
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

請求轉發(請求轉發的時候不跳轉url 只是頁面跳轉)

public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/servletDemo03");  //轉發的請求路徑
        requestDispatcher.forward(req, resp); //會進入servletDemo03界面 但是url還是在servletDemo04 
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

在這裏插入圖片描述

讀取資源文件
Properties

  • 在java目錄下新建properties
  • 在resources目錄下新建properties
    發現:都被打包到了同一路徑下,classes,我們俗稱爲這個路徑爲classPath
    在這裏插入圖片描述
    如果將properties放在java目錄下,資源可能會導出失敗,在pom.xml中配置
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

默認不需要配置resources目錄

思路:需要一個文件流

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(is);
        String user = (String) properties.get("user");
        System.out.println(user);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
HttpServletRequest

HttpServletRequest代表客戶端的請求,用戶通過Http協議訪問服務器,HTTP請求中的所有細信息會被封裝到HttpServletRequest,通過這個HttpServletRequest的方法,獲得客戶端的所有信息

  1. 獲取前端傳遞的參數
    在這裏插入圖片描述
  2. 請求轉發
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        // 獲取參數
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
		// 請求轉發
        req.getRequestDispatcher("/success.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
HttpServletResponse

web服務器接收到客戶端的http請求,針對這個請求,分別創建一個代表請求的HttpServletRequest對象,代表響應的一個HttpServletResponse;

  • 如果想要獲取客戶端請求過來的參數:找HttpServletRequest
  • 如果想要給客戶端響應一些信息,找HttpServletResponse
  1. 簡單分類
    負責向瀏覽器發送數據的方法:
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;

向瀏覽器發送響應頭的方法

 	void setCharacterEncoding(String var1);

    void setContentLength(int var1);

    void setContentLengthLong(long var1);

    void setContentType(String var1);
    
    void setDateHeader(String var1, long var2);

    void addDateHeader(String var1, long var2);

    void setHeader(String var1, String var2);

    void addHeader(String var1, String var2);

    void setIntHeader(String var1, int var2);

    void addIntHeader(String var1, int var2);

常見應用:

  1. 向瀏覽器輸出信息
  2. 下載文件
    1. 獲取下載文件的路徑
    2. 下載的文件名
    3. 設置想辦法讓瀏覽器支持下載我們需要的東西
    4. 獲取下載文件的輸入流
    5. 創建緩衝區
    6. 獲取OutputStream對象
    7. 將FileInputStream流寫入到buffer緩衝區 使用OutputStream將緩衝區中的數據輸出到客戶端
    8. 關閉資源
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1. 獲取下載文件的路徑
        String realPath = this.getServletContext().getRealPath("/1.jpg");
        System.out.println("文件路徑:" + realPath);
//        2. 下載的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);
//        3. 設置想辦法讓瀏覽器支持下載我們需要的東西
        resp.setHeader("Content-disposition", "attachment;filename" + fileName);
//        4. 獲取下載文件的輸入流
        FileInputStream in = new FileInputStream(realPath);
//        5. 創建緩衝區
        int len = 0;
        byte[] buffer = new byte[1024];
//        6. 獲取OutputStream對象
        ServletOutputStream out = resp.getOutputStream();
//        7. 將FileInPutStream流寫入到buffer緩衝區 使用OutputStream將緩衝區中的數據輸出到客戶端
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }
//        8. 關閉資源
        in.close();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  1. 驗證碼
public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 如何讓瀏覽器五秒自動刷新一次
        resp.setHeader("refresh", "5");

        //在內存中創建一個圖片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = (Graphics2D) image.getGraphics(); //筆
        // 設置背景顏色
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, 80, 20);
        //給圖片寫數據
        graphics.setColor(Color.BLUE);
        graphics.setFont(new Font(null, Font.BOLD, 20));
        graphics.drawString(makeNum(), 0, 20);

        //告訴瀏覽器這個請求用圖片的方式打開
        resp.setContentType("image/jpeg");
        //網站存在緩存 不讓瀏覽器緩存
        resp.setDateHeader("expires", -1);
        resp.setHeader("Cache-Control", "no-cache");
        resp.setHeader("Pragma", "no-cache");

        //把圖片寫給瀏覽器
        ImageIO.write(image, "jpg", resp.getOutputStream());
    }

    //生成隨機數
    private String makeNum() {
        Random random = new Random();
        String num = String.valueOf(random.nextInt(9999999));
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7 - num.length(); i++) {
            sb.append("0");
        }
        num = sb.toString() + num;
        return num;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  1. 實現重定向
    一個web資源收到客戶端請求後,會通知客戶端去訪問另外一個web資源,這個過程叫重定向
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        重定向等價於這兩步
        resp.setHeader("Location", "/image");
        resp.setStatus(HttpServletResponse.SC_FOUND);
         */
        resp.sendRedirect("/image"); //重定向

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

重定向和轉發的區別

  • 相同點:頁面跳轉
  • 不同點:
    • 轉發 url不變 307
    • 重定向 url跳轉 302
public class RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("進入請求");
        //處理請求
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username+":"+password);
        resp.sendRedirect("/success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

<html>
<body>
<h2>Hello World!</h2>

<%-- 這裏提交的路徑需要尋找到項目的路徑--%>
<%--${pageContext.request.contextPath} 當前項目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用戶名: <input type="text" name="username"><br>
    密碼:<input type="password" name="password"><br>
    <input type="submit">
</form>
</body>
</html>


    <servlet>
        <servlet-name>request</servlet-name>
        <servlet-class>com.wang.servlet.RequestTest</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>request</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

Cookie Session

cookie

  • 客戶端技術(響應請求)
    session
  • 服務器技術,利用這個技術可以保存用戶的會話信息,我們可以把信息或者數據放在session中

常見場景:網站登錄之後下次不用登錄,第二次訪問自動登錄

Cookie
  1. 從請求中拿到cookie信息
  2. 服務器響應給客戶端cookie
 Cookie[] cookies = req.getCookies(); //獲得Cookie
 cookie.getName();  //獲得Cookie的key
 cookie.getValue(); //獲得Cookie的value
 Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis())); //新建一個cookie
 cookie.setMaxAge(24 * 60 * 60); //設置cookie有效期
 resp.addCookie(cookie);

public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        PrintWriter out = resp.getWriter();

        // cookie 服務端從客戶端獲取
        Cookie[] cookies = req.getCookies();

        if (cookies != null) {
            out.write("上次訪問的時間是");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //獲取cookie的名字
                if (cookie.getName().equals("lastLoginTime")) {
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }
            }
        } else {
            out.write("這是你第一次訪問本站");
        }

        //服務器給客戶端響應一個cookie
        Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis()));
        cookie.setMaxAge(24 * 60 * 60);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 一個Cookie只能保存一個信息 key-value
  • 一個web站點可以給瀏覽器發送多個cookie,300個cookie大概是瀏覽器上限,每個站點最多存放20個
  • cookie大小有限制,4Kb

刪除Cookie:

  • 不設置有效期,關閉瀏覽器自動失效
  • 設置有效期時間爲0
// 網絡編程解決亂碼
String encode = URLEncoder.encode("我是中文", "utf-8");
String decode = URLDecoder.decode(encode, "utf-8");
Session

什麼是session

  • 服務器會給每一個用戶(瀏覽器)創建一個Session對象
  • 一個Session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個Session就存在
  • 用戶登錄之後,整個網站都可以訪問
public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解決亂碼問題
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到session
        HttpSession session = req.getSession();
        // 給session存東西
        session.setAttribute("name", "nameTest");
        session.getAttribute("name");
        // 手動註銷
        session.removeAttribute("name");

        //獲得session的id
        String id = session.getId();

        //判斷session是不是新的
        if (session.isNew()) {
            resp.getWriter().write("session創建成功,id" + id);
        } else {
            resp.getWriter().write("session已經在服務器中存在,id" + id);
        }

        //session在創建的時候做了什麼
//        Cookie cookie = new Cookie("JSESSIONID", id);
//        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    <!--  設置session默認的失效時間 15分鐘-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

使用場景:

  • 保存一個登錄用戶的信息
  • 購物車信息
  • 在整個網站中經常會使用的數據,保存在session中

Session和Cookie的區別:

  • Cookie是把用戶的數據寫給用戶的瀏覽器,瀏覽器保存
  • Session是把用戶的數據寫到用戶獨佔的Session中,服務器端保存(保存重要的信息,減少服務器資源浪費)
  • Session對象由服務器創建

JSP

什麼是JSP

Java Server Pages:Java服務器端頁面,也和Servlet一樣,用於動態web技術
最大的特點:

  • 寫JSP就像在寫HTML
  • 區別:
    • HTML給用戶提供靜態的數據
    • JSP頁面可以嵌入JAVA代碼,提供動態數據
JSP原理

思路:JSP是怎麼執行的

  • 服務器內部:
    tomcat中有一個work目錄
    IDEA中使用Tomcat的會在IDEA中生成一個work目錄(工作空間 仍然依託於自己的tomcat)
/Users/wangyinghao/Library/Caches/JetBrains/IntelliJIdea2020.1/tomcat/Unnamed_kuangshen-javaweb/work/Catalina/localhost/ROOT/org/apache/jsp

在這裏插入圖片描述
瀏覽器向服務器發送請求,不管訪問什麼資源,其實都是在訪問Servlet
JSP最終也會被轉換成一個Java類
JSP本質就是一個Servlet

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.22
 * Generated at: 2020-05-31 03:39:28 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
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,
                 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;
  }

  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() {
  }
//JspService
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

//request 請求 response 響應
    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");
        return;
      }
    }

// 內置對象
    final javax.servlet.jsp.PageContext pageContext; //頁面上下文
    javax.servlet.http.HttpSession session = null; //session
    final javax.servlet.ServletContext application; //applicationContext
    final javax.servlet.ServletConfig config; //config
    javax.servlet.jsp.JspWriter out = null; //out
    final java.lang.Object page = this; //page
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
    // 輸出頁面前增加的代碼
      response.setContentType("text/html"); //設置響應的頁面類型 html
      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;
// 以上的這些對象可以在JSP頁面中直接使用
// ${pageContext}
      out.write("<html>\n");
      out.write("<body>\n");
      out.write("<h2>Hello World!</h2>\n");
      out.write("</body>\n");
      out.write("</html>\n");
    } 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);
    }
  }
}

在這裏插入圖片描述
在JSP頁面中,只要是JAVA代碼就會被原封不動的輸出;如果是HTML代碼,就會被轉換成

out.write("<html>\r\n");

JSP基礎語法

<html>
<body>
<h2>Hello World!</h2>


<%--JSP表達式--%>
<%--作用 將程序的輸出輸出到客戶端--%>
<%=new java.util.Date()%>

<hr/>

<%--腳本片段--%>
<%
    int sum = 0;
    for (int i = 0; i < 100; i++) {
        sum += i;
    }
    out.println("<h1> Sum=" + sum + "</h1>");
%>

<%--代碼中嵌入html--%>
<%
    for (int i = 0; i < 5; i++) {
%>
<h1>Hello,world  <%=i%></h1>
<%
    }
%>

<%--EL表達式  ${i}--%>

<%--JSP聲明--%>
<%--會被編譯到JSP生成Java類的類中 而不是_jspService中--%>
<%!
   static {
       System.out.println("Loading servlet");
   }
   private int globalVar = 0;
   public void test(){
       System.out.println("test");
   }
%>
</body>
</html>
9大內置對象
  • PageContext 存東西
  • Request 存東西
  • Response
  • Session 存東西
  • Application ServletContext 存東西
  • config ServletConfig
  • out
  • page
  • exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--內置對象--%>
<%
    pageContext.setAttribute("name1", "name1"); //保存的數據只在一個頁面有效
    request.setAttribute("name2", "name2"); //保存的數據只在一次請求中有效 請求轉發會攜帶這個數據
    session.setAttribute("name3", "name3"); // 保存的數據只在一次會話中有效 從打開瀏覽器到關閉瀏覽器
    application.setAttribute("name4", "name4"); //保存的數據在服務器中有效 從打開服務器到關閉服務器
%>

<%
    // 通過pageContext取,我們通過尋找的方式
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
    // pageContext有個類似JVM的雙親委派機制的特性 從底層到高層(作用域) page-->request-->session-->application

// pageContext.setAttribute() scope爲作用域 也可以提升pageContext的作用域
public void setAttribute(String name, Object attribute, int scope) {
        switch(scope) {
        case 1:
            this.mPage.put(name, attribute);
            break;
        case 2:
            this.mRequest.put(name, attribute);
            break;
        case 3:
            this.mSession.put(name, attribute);
            break;
        case 4:
            this.mApp.put(name, attribute);
            break;
        default:
            throw new IllegalArgumentException("Bad scope " + scope);
        }
%>

<%--通過el表達式輸出--%>
<h1>取出的值爲:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
</body>
</html>

request:客戶端向服務器發送請求,產生的數據,用戶看完就沒用的,比如:用戶看新聞
session:客戶端向服務器發送請求,產生的數據用戶用完一會還會用,比如:購物車
application:客戶端向服務器發送請求,產生的數據,一個用戶用完其他用戶還可能使用,比如:聊天數據

JSP標籤 JSTL標籤 EL表達式

EL表達式: ${}
  • 獲取數據
  • 執行運算
  • 獲取web開發的常用對象
JSP標籤
<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="nameTest"/>
    <jsp:param name="age" value="ageTest"/>
</jsp:forward>

<%--取出參數--%>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>
JSTL標籤

JSTL標籤庫的使用就是爲了彌補HTML標籤的不足:自定義了許多標籤,功能和java一樣

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--導入JSTL核心庫--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<hr/>

<form action="coreif.jsp" method="get">
    <%--    EL表達式獲取表單中的數據--%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登錄">
</form>

<%--判斷如果提交的用戶名是管理員 則登錄成功--%>
<c:if test="${param.username == 'admin'}" var="isAdmin">
    <c:out value="管理員歡迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>

<%
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"張三");
    people.add(1,"李四");
    request.setAttribute("list",people);
%>

<c:forEach var="people" items="${list}">
    <c:out value="${people}"></c:out><br>
</c:forEach>

</body>
</html>

JavaBean

實例類
JavaBean有特定的寫法:

  • 必須要有一個無參構造
  • 屬性必須私有化
  • 必須有對應的get/set方法
    一般用來和數據庫的字段做映射
    ORM:對象關係映射
  • 表–>類
  • 字段–>屬性
  • 行記錄–>對象
<%@ page import="com.wang.pojo.People" %><%--
  Created by IntelliJ IDEA.
  User: wangyinghao
  Date: 2020/5/31
  Time: 5:13 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%
//    People people = new People();
//    people.setId(1);
//    people.setAddress("上海");
//    people.setAge(10);
//    people.setName("wyh");
%>
<jsp:useBean id="people" class="com.wang.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="上海"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="10"/>
<jsp:setProperty name="people" property="name" value="wyh"/>

姓名:<jsp:getProperty name="people" property="name"/>

</body>
</html>

MVC三層架構

在這裏插入圖片描述
Model:

  • 業務處理:業務邏輯 Service
  • 數據持久層:CRUD Dao
    View
  • 展示數據
  • 提供鏈接發起Servlet請求
    Controller
  • 接收用戶的請求:req請求 session信息…
  • 交給業務層處理對應的代碼
  • 控制視圖的跳轉
登錄-->接收用戶的登錄請求-->處理用戶的請求(獲取用戶登錄的參數,username pwd)-->交給業務層處理登錄業務(判斷用戶名密碼是否正確:事務)-->Dao層查詢用戶名和密碼是否正確-->數據庫

Filter

過濾器,用來處理網站的數據
在這裏插入圖片描述

public class CharacterEncodingFilter implements Filter {

    //服務器啓動的時候 init就已經初始化 隨時等待監聽
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init");
    }

    //Chain 鏈
    // 過濾所有的代碼 在過濾特定請求的時候都會執行 web.xml配置
    // 必須要讓過濾器繼續執行  filterChain.doFilter(servletRequest, servletResponse);
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        System.out.println("doFilter執行前");
        filterChain.doFilter(servletRequest, servletResponse); //讓我們的請求繼續走 如果不寫程序就到這裏被攔截停止
        System.out.println("doFilter執行後");
    }

    //web服務器關閉的時候銷燬
    public void destroy() {
        System.out.println("destroy");
    }
}
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.wang.filter.CharacterEncodingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--        只要是/下的任何請求都會經過這個過濾器-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章