1. 程式人生 > 實用技巧 >匿名/遞迴函式

匿名/遞迴函式

JavaWeb

1.web的基本概念

web開發

  • web 網頁
  • 靜態web
    • html,css
    • 提供給所有人的資料始終不會發生變化
  • 動態web
    • Servlet/JSP,ASP,PHP
    • 提供給人看的資料始終會發生變化,每個人在不同時間不同地點看到的都不一樣

web應用程式

定義:可以提供瀏覽器訪問的程式

  • a.html, b.html ......多個web資源,這些web資源可以被外界訪問
  • 任何一個介面或者資源,都存在於某一個角落的計算機上
  • 組成部分:html,css,js,jsp,servlet,java程式, jar包,配置檔案......
  • web應用程式編寫完畢後,若想提供給外界訪問,需要一個伺服器來統一管理

靜態web

  • 缺點:
    • 頁面無法更新
    • 無法和資料庫互動

動態web

2.web伺服器

技術

ASP

  • 微軟: 國內最早流行的ASP
  • 在HTML中嵌入VB的指令碼, ASP+COM;
  • 在開發中,基本一個頁面中有業務程式碼,頁面極其混亂

PHP

  • 開發速度很快,功能強大,跨平臺,程式碼簡單
  • 無法承載大訪問量的情況(侷限性)

JSP/Servlet

  • sun公司主推的B/S架構 B/S:瀏覽器和伺服器 C/S:客戶端和伺服器
  • 給予java語言的(所有的大公司,或者一些開源的元件都是用java寫的)
  • 可以承載三高問題帶來的影響

web伺服器

伺服器是一種被動的操作,用來處理使用者的一些請求和給使用者一些響應資訊

IIS

  • ASP...Windows中自帶

Tomcat

  • 面向百度程式設計:

  • Tomcat是Apache 軟體基金會(Apache Software Foundation)的Jakarta 專案中的一個核心專案,最新的Servlet 和JSP 規範總是能在Tomcat 中得到體現,Tomcat 5支援最新的Servlet 2.4 和JSP 2.0 規範。因為Tomcat 技術先進、效能穩定,而且免費,因而深受Java 愛好者的喜愛並得到了部分軟體開發商的認可,成為目前比較流行的Web 應用伺服器。

    Tomcat 伺服器是一個免費的開放原始碼的Web 應用伺服器,屬於輕量級應用伺服器

    ,在中小型系統和併發訪問使用者不是很多的場合下被普遍使用,是開發和除錯JSP 程式的首選。對於一個初學者來說,它是最佳的選擇。

    Tomcat 實際上執行JSP 頁面和Servlet。目前Tomcat最新版本為9.0.37

3.Tomcat

  1. 資料夾資訊

  1. 開啟與關閉服務
  1. 伺服器配置檔案

  • 可以配置埠號
    • tomcat的預設埠號為:8080
    • mysql:3306
    • http:80
    • https:443
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

可以配置主機名稱

  • 預設主機名:localhost-->127.0.0.1
  • 預設網站應用存放的位置為:webapps
<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

請你談談網站是如何進行訪問的!

  1. 輸入一個域名:回車

  2. 檢查本機的 C:\WINDOWS\System32\drivers\etc\hosts配置檔案下有沒有這個域名對映

    • 有:直接返回對應的ip地址,這個地址中,有我們需要的web程式,可以直接訪問
    • 沒有:去DNS伺服器找,找到就返回,找不到就返回找不到

釋出一個web網站

  • 將自己的網站,放到伺服器(tomcat)中指定的web應用的資料夾下,就可以成功訪問

網站應該有的結構

--webapp: 
	-ROOT
	-lk
		-WEB-INF
			-classes: java程式
			-lib: web應用所依賴的jar包
			-web.xml
		-index.html
		-static
			-css
				-style.css
			-js
			-img

4.http

4.1、什麼是http

http(超文字傳輸協議)是一個簡單的請求-響應協議,它通常執行在TCP之上。

  • 文字:html、字串......
  • 超文字:圖片、音樂、視訊、定位、地圖......

https:多了個s表示它是安全的

4.2、兩個時代

  • http 1.0
    • HTTP/1.0:客戶端與web伺服器連線後,只能獲得一個web資源,斷開連線。
  • http 2.0
    • HTTP/1.1:客戶端與web伺服器連線後,可以獲得多個web資源。

4.3、http請求

  • 客戶端--發請求(Resquest)--伺服器

百度:

Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote(遠端) Address: 180.101.49.11:443
Referrer Policy: unsafe-url
Accept:text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
  1. 請求行

    • 請求行中的請求方式:GET
    • 請求方式:GET/POST
      • get:請求能夠攜帶的引數比較少,大小有限制,會在瀏覽器的URL位址列中顯示資料內容,不安全,但高效
      • post:請求能夠攜帶的引數沒有限制,大小沒有限制,不會在瀏覽器的URL位址列中顯示資料內容,安全,但不高效

  2. 訊息頭

    Accept: 告訴瀏覽器,它所支援的資料型別
    Accept-Encoding: 支援哪種編碼格式GBK UTF-8 GB2312 ISO8859-1
    Accept-Language: 告訴瀏覽器,它的語言環境
    Cache-Control: 快取控制
    Connection: 告訴瀏覽器,請求完成是斷開還是保持連線
    HOST:主機
    

4.4、http響應

  • 伺服器--響應--客戶端

百度:

Cache-Control: private     快取控制
Connection: keep-alive     連線
Content-Encoding: gzip     編碼
Content-Type: text/html;charset=utf-8  型別
  1. 響應體

    Accept: 告訴瀏覽器,它所支援的資料型別
    Accept-Encoding: 支援哪種編碼格式GBK UTF-8 GB2312 ISO8859-1
    Accept-Language: 告訴瀏覽器,它的語言環境
    Cache-Control: 快取控制
    Connection: 告訴瀏覽器,請求完成是斷開還是保持連線
    HOST:主機
    REFRESH:告訴客戶端,多久重新整理一次
    Location:讓網頁重新定位
    
  2. 響應狀態碼

    • 200:請求響應成功 200

    • 3xx:請求重定向

      • 重定向:你重新到我給你的新位置去
    • 4xx:找不到資源 404

      • 資源不存在
    • 5xx:伺服器程式碼錯誤 500

      • 502:閘道器錯誤

常見面試題:

當你的瀏覽器中位址列輸入地址並回車的一瞬間,到頁面能夠展示回來,經歷了什麼?

5、Maven

我為什麼要學這個技術

  1. 在javaweb開發中,需要使用大量的jar包,我們手動去匯入;

  2. 如何能夠讓一個東西自動幫我匯入和配置jar包

    由此,Maven誕生了

5.1、Maven專案架構管理工具

我們目前用來就是方便匯入jar包的!

Maven的核心思想:約定大於配置

  • 有約束,不要去違反。

Maven會規定好你該如何去編寫我們的java程式碼,必須要按照這個規範來

5.2、安裝Maven

https://maven.apache.org/

  1. 下載解壓
  2. 配置環境變數
    • M2_HOME
    • MAVEN_HOME
    • 在系統的path中配置 %MAVEN_HOME%\bin
    • 測試 cmd :mvn -version

  1. 配置aliyun映象

    //加速下載
    <mirror>
    	  <id>nexue-aliyun</id>
    	  <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
    	  <name>Nexus maven</name>
    	  <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
    
  2. 建立本地倉庫

5.3、在IDEA中使用Maven

  1. 啟動IDEA

  2. 建立Maven專案

  3. 更改maven配置

  4. Maven目錄結構

5.4、Maven倉庫的使用

https://mvnrepository.com/

6、Servlet

6.1、什麼是Servlet

  • Servlet就是sun公司開發動態web的一門技術
  • Sun再這些API中提供一個介面叫做:Servlet 如果想開發一個Servlet程式,只需要完成兩個小步驟
    • 編寫一個類,實現Servlet介面
    • 把開發好的java類部署到web伺服器中

把實現了Servlet介面的java程式叫做Servlet

6.2、HelloServlet

Servlet介面Sun公司有兩個預設的實現類:HttpServlet,GenericServlet

  1. 建立一個Maven專案,刪掉裡面的src目錄,這個空的工程就是Maven的主工程。

  2. 關於Maven父子工程的理解:

    父專案會有

    <modules>
            <module>servlet-01</module>
    </modules>
    

    子專案中會有

    <parent>
            <artifactId>javaweb</artifactId>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
    </parent>
    

    父專案中的java子專案可以直接使用

    son extends father
    
  3. Maven環境優化

    • 修改web.xml為最新的
    • 將maven的結構搭建完整
  4. 編寫一個Servlet程式

    • 編寫一個普通類

    • 實現Servlet介面,這裡我們直接繼承HttpServlet

    • public class HelloServlet extends HttpServlet {
          //由於get或者post只是請求實現的不同的方式,可以相互呼叫,業務邏輯都一樣。
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              PrintWriter printWriter =  resp.getWriter();
              printWriter.println("hello, lk!");
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
  5. 編寫地址對映

    為什麼需要對映:我們寫的是java程式,但是要通過瀏覽器訪問,而瀏覽器需要連線web伺服器,所以我們需要在web伺服器中註冊我們寫的Servlet,還需要給他一個瀏覽器能夠訪問的路徑。

    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.lk.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
  6. 配置Tomcat

  7. 啟動專案

6.3、Servlet原理

Servlet是由web伺服器呼叫,web伺服器在收到瀏覽器請求之後,會:

6.4、Mapping問題

  1. 一個Servlet可以指定一個對映路徑。

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
  2. 一個Servlet可以指定多個對映路徑。

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    
  3. 一個Servlet可以指定通用對映路徑。

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
    
  4. 預設請求路徑。(少用,因為這個會代替index.jsp)

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
  5. 自定義字尾實現請求對映,注:*前面不能加專案對映的路徑。

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.lk</url-pattern>     //  *前面加上/會報錯
    </servlet-mapping>
    
  6. 優先順序問題

    指定了固有的對映路徑優先順序最高,如果找不到就會走預設的請求路徑

6.5、ServletContext

web容器在啟動的時候,他會為每個web程式都建立一個對應的ServletContex物件,它代表了當前的web應用;

  1. 共享資料

    //在一個servlet類中將引數儲存到ServletContext中
    ServletContext context = this.getServletContext();
    context.setAttribute("username","劉科");
    
    //在另一個servlet類中獲取儲存的引數
    ServletContext context = this.getServletContext();
    String username = (String)context.getAttribute("username");
    
  2. 獲取初始化引數

    //在web.xml檔案中配置引數
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306</param-value>
    </context-param>
        
    //在servlet類中可以獲取
    ServletContext context = this.getServletContext();
    String param = context.getInitParameter("url");
    resp.getWriter().println(param);
    
  3. 請求轉發

    //請求路徑不變,頁面顯示的是/pm路徑下的頁面
    context.getRequestDispatcher("/pm").forward(req, resp);
    
  4. 讀取資原始檔

    properties

    • 在java目錄下新建properties
    • 在resources目錄下新建properties

    發現:都被打包到了同一個路徑下:classes,俗稱這個路徑為:classpath

    思路:需要一個檔案流

    //properties檔案
    username=root
    password=123456
    
    InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/lk.properties");
    Properties properties = new Properties();
    properties.load(is);
    String user = properties.getProperty("username");
    String pwd = properties.getProperty("password");
    

6.6、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);
    

    響應狀態碼

    int SC_OK = 200;
    int SC_NOT_FOUND = 404;
    int SC_INTERNAL_SERVER_ERROR = 500;
    int SC_BAD_GATEWAY = 502;
    
  2. 常見應用

    1. 向瀏覽器輸出資訊

    2. 下載檔案

      ​ 1.要獲取下載檔案的路徑

      ​ 2.下載的檔名是啥

      ​ 3.設定讓瀏覽器能夠支援下載我們需要的東西

      ​ 4.獲取下載檔案的輸入流

      ​ 5.建立緩衝區

      ​ 6.獲取OutputStream物件

      ​ 7.將FileOutputStream流寫入到buffer緩衝區中

      ​ 8.使用OutputStream將緩衝區中的資料輸出到客戶端

      //1.要獲取下載檔案的路徑
      String realPath = "D:\\javaprogram\\javaweb\\servlet-03\\src\\main\\resources\\1.png";
      
      //2.下載的檔名是啥
      String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
      
      //3.設定讓瀏覽器能夠支援下載我們需要的東西
      resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));
      
      //4.獲取下載檔案的輸入流
      FileInputStream in = new FileInputStream(realPath);
      
      //5.建立緩衝區
      int len = 0;
      byte[] buffer = new byte[1024];
      
      //6.獲取OutputStream物件
      ServletOutputStream out = resp.getOutputStream();
      
      //7.將FileOutputStream流寫入到buffer緩衝區中,使用OutputStream將緩衝區中的資料輸出到客戶端!
      while ((len=in.read(buffer))>0){
      out.write(buffer, 0, len);
      }
      
      in.close();
      out.close();
      
  3. 驗證碼功能

    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //讓瀏覽器3秒重新整理一次
            resp.setHeader("refresh","3");
    
            //在記憶體中建立一個圖片
            BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
            //得到圖片
            Graphics2D g = (Graphics2D) image.getGraphics();
            //設定圖片的背景顏色
            g.setColor(Color.white);
            g.fillRect(0,0,80,20);
            //給圖片寫資料
            g.setColor(Color.BLUE);
            g.setFont(new Font(null, Font.BOLD, 20));
            g.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 = random.nextInt(9999)+"";
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 4-num.length(); i++) {
                sb.append(0);
            }
            num = sb.toString() + num;
            return num;
        }
    
  4. 實現重定向

    一個web資源收到客戶端請求後,他會通知客戶端去訪問另外一個web資源,這個過程就叫做重定向。

    常見場景:

    • 使用者登入

      void sendRedirect(String var1) throws IOException;
      
      //方法一
      resp.setHeader("location","/servlet_03_war/random");
      resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
      //方法二
      resp.sendRedirect("/servlet_03_war/random");
      

​ 面試題:請你聊聊重定向和轉發的區別?

​ 相同點:都會跳轉頁面

​ 不同點:重定向位址列會發生變化,而轉發的url不會發生變化。

​ 重定向-302 轉發:307

6.7、HttpServletRequest

獲取引數,請求轉發

req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");

String user = req.getParameter("username");
String pwd = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");

System.out.println("username:" + user);
System.out.println("password:" + pwd);
System.out.println(Arrays.toString(hobbys));

req.getRequestDispatcher("/succeed.jsp").forward(req, resp);

7、Cookie,Session

7.1、會話

**會話 **:使用者開啟一個瀏覽器,點選了好多超連結,訪問多個web資源,最後關閉瀏覽器,這個過程稱為會話。

**有狀態會話: **一個同學來過教室,下次再來教室,我們就會知道這個同學曾經來過,稱之為狀態會話。

你能怎麼證明你是西開的學生?

1.發票

2.學校登記

一個網站,怎麼證明你來過?

客戶端 服務端

  1. 服務端給客戶端一個信件,客戶端下次訪問伺服器,帶上信件就可以了; cookie

  2. 伺服器登記你來過了,下次你來我匹配你;session

7.2、儲存會話的兩種技術

cookie

  • 客戶端技術(響應,請求)

session

  • 伺服器技術,利用這個技術,可以儲存使用者的會話資訊。我們可以把資訊或者資料放在session中

常見場景:網站登入之後,你下次不用再登入了,第二次訪問直接就上去了。

7.3、Cookie

  1. 從請求中拿到cookie資訊

  2. 伺服器響應給客戶端cookie

    //獲取cookie
    Cookie[] cookies = req.getCookies();
    //獲取cookie的key
    req.cookie.getName()
    //獲取cookie的value
    cookie.getValue()
    //新建一個cookie
    new Cookie("LastTime", System.currentTimeMillis()+"");
    //設定cookie的有效期
    cookie.setMaxAge(24*60*60);
    //響應給客戶端cookie
    resp.addCookie(cookie);
    

一個網站cookie是否村子啊上限:

  • 一個cookie只能儲存一個資訊;
  • 一個web站點可以給瀏覽器傳送多個cookie,最多20個
  • cookie大小有限制4kb
  • 瀏覽器上限大約300個cookie

刪除cookie:

  • 不設定有效期,關閉瀏覽器,自動失效
  • 設定有效期時間為0

編碼解碼:

  • URLEncoder.encode("可可","utf-8");
  • URLDecoder.decode(str,"utf-8");

7.4、Session(重點)

什麼是Session

  • 伺服器會給每一個使用者(瀏覽器)建立一個Session物件
  • 一個Session獨佔一個瀏覽器,只要瀏覽器沒有關,這個Session就存在
  • 使用者登入之後,整個網站它都可以訪問-->儲存使用者的資訊,儲存購物車的資訊...

Session和Cookie的區別

  • Cookie是把使用者的資料寫給使用者的瀏覽器,瀏覽器儲存(可以儲存多個)
  • Session把使用者的資料寫到使用者獨佔的Session中,伺服器中儲存(儲存重要的東西,減少伺服器資源的浪費)
  • Session物件由服務建立

使用場景:

  • 儲存一個登入使用者的資訊;
  • 購物車資訊;
  • 再整個網站中經常會使用的資料,我們將它儲存在Session中;

使用Session

//獲取Session
HttpSession session = req.getSession();
//給Session賦值
session.setAttribute("person", new Person("可可", 22));
//顯示id
String id = session.getId();
resp.getWriter().write(id);

//獲取其他Servlet中的Session值
HttpSession session = req.getSession();
//輸出Session值
Person person = (Person) session.getAttribute("person");
//resp.getWriter().write(person.toString());
System.out.println(person.toString());

//手動登出Session
HttpSession session = req.getSession();
session.removeAttribute("person");
session.invalidate();

會話自動過期

<!--以分鐘為單位-->
<session-config>
    <session-timeout>1</session-timeout>
</session-config>

8、JSP

8.1、什麼是JSP

java Server Pages: java伺服器端頁面,也和servlet一樣用於開發動態web技術

最大的特點:

  • 寫JSP就像在寫HTML
  • 區別:
    • HTML只給使用者提供靜態的資料
    • JSP頁面中可以嵌入JAVA程式碼,為使用者提供動態資料;

8.2、JSP原理

思路:JSP到底怎麼執行的!

  • 程式碼層面沒有任何問題

瀏覽器向伺服器傳送請求,不管訪問什麼資源,其實都是在訪問Servlet

JSP最終也會被轉換成為一個JAVA類

**JSP本質上也是一個servlet **

//初始化
public void _jspInit(){
    
}
//銷燬
public void _jspDestroy(){
    
}
//JSPService
public void _jspService(HttpServletRequest request,HttpServletResponse response){
    
}
  1. 判斷請求
  2. 內建一些物件
final javax.servlet.jsp.PageContext pageContext;      //頁面上下文
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.http.HttpSession session = null;        //session
HttpServletRequest request                            //請求
HttpServletResponse response                          //響應
  1. 輸出頁面前增加的程式碼
response.setContentType("text/html; charset=UTF-8");   //設定響應的頁面型別
pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, false, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
  1. 以上的這些個物件我們可以在JSP頁面中直接使用!

在JSP頁面中:

只要是JAVA程式碼就會原封不動地輸出;

如果是HTML程式碼,就會被轉化為

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

這樣的格式,輸出到前端!

8.3、JSP基礎語法

任何語言都有自己的語法,JAVA中有,JSP作為java技術的一種應用,它擁有一些自己擴充的語法(瞭解,知道即可!)java所有語法都支援!

**JSP表示式 **

<%-- 作用:用來將程式的輸出,輸出到客戶端--%>
<%= new java.util.Date()%>

<%-- 格式--%>
<%= 變數或者表示式%>

**JSP指令碼片段 **

<%-- jsp指令碼片段--%>
<%
	int sum = 0;
	for (int i=1; i<=100; i++){
        sum+=i;
    }
	out.println("<h1>Sum="+sum+"</h1>")
%>

**JSP宣告 **

<%!
    static{
    	System.out.println("Loading Servlet!")
	}
	private int globalvar = 0;
	public void kuang(){
        System.out.println("進入了方法kuang")
    }
%>

JSP宣告:會被編譯到JSP生成的java類中!其他的,就會被生產到_jspService方法中!

在JSP,嵌入java程式碼即可

<% %>
<%= %>
<%! %>

<%--註釋--%>

JSP的註釋,不會在客戶端顯示,HTML就會!

8.4、JSP指令

<%@ page args....%>
<%@ include file=""%>

//include會將兩個頁面合二為一
<%@ include file="common/header.jsp"%>
<h1>網頁主體</h1>
<%@ include file="common/footer.jsp"%>

//jsp標籤-->jsp:include 拼接頁面,本質上還是三個
<jsp:include page="/common/header.jsp">
<h1>網頁主體</h1>
<jsp:include page="/common/footer.jsp">

8.5、九大內建物件

  • Pagecontext 存東西
  • Resquest 存東西
  • Response
  • Session 存東西
  • Application 【ServletContext】存東西
  • config 【ServletConfig】
  • out
  • page 不用瞭解
  • exception
pageContext.setAttribute("name1","可可1號"); //儲存的資料只在一個頁面有效
request.setAttribute("name2","可可2號");  //儲存的資料只在一次請求中有效,請求轉發會攜帶這個資料
session.setAttribute("name3","可可3號");  //儲存的資料只在一次會話中有效,從開啟瀏覽器到關閉瀏覽器
application.setAttribute("name4","可可4號");  //儲存的資料只在伺服器中有效,從開啟伺服器到關閉伺服器

EL表示式輸出
${name1}

requeset:客戶端向伺服器傳送請求,產生的資料,使用者看完了就沒用了,比如:新聞

session:客戶端向伺服器傳送請求,產生的資料,使用者用完一會還有用,比如:購物車

application:客戶端向伺服器傳送請求,產生的資料,一個使用者用完了,其他使用者還能接著使用,比如:聊天資料。

8.6、JSP標籤,JSTL標籤,EL表示式

<!-- JSTL表示式的依賴 -->
<dependency>
        <groupId>javax.servlet.jsp.jstl</groupId>
        <artifactId>jstl-api</artifactId>
        <version>1.2</version>
</dependency>
<!-- standard標籤庫 -->
<dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
</dependency>

EL表示式:${}

  • 獲取資料
  • 執行運算
  • 獲取web開發的常用物件

JSP標籤

<jsp:include page="/common/header.jsp">
<jsp:forward page="/jsptag2.jsp"></jsp:forward>
<jsp:param name="name" value="lk"></jsp:param>

JSTL表示式

JSTL標籤庫的使用就是為了彌補HTML標籤的不足;它自定義許多標籤,可以供我們使用,標籤的功能和java程式碼一樣!

核心標籤(掌握部分即可)

JSTL標籤庫使用步驟:

  • 引入對應的taglib
  • 使用其中的方法
  • 在Tomcat 也需要引入jstl的包
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

c:if 測試

<form action="coreif.jsp" method="get">
    <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:if>
<c:out value="${isAdmin}"/>

c:choose 測試

<c:set var="score" value="70"/>

<c:choose>
    <c:when test="${score>=90}">
        你的成績為優秀
    </c:when>
    <c:when test="${score>=80}">
        你的成績為一般
    </c:when>
    <c:when test="${score>=70}">
        你的成績為良好
    </c:when>
    <c:when test="${score<60}">
        你的成績為不及格
    </c:when>
</c:choose>

c:foreach 測試

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

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

<c:forEach var="people" items="${list}" begin="1" end="3" step="1">
    <c:out value="${people}"/><br>
</c:forEach>

9、JavaBean

10、MVC三層架構

什麼是MVC:Model,view,Controller 模型,檢視,控制器

10.1、早些年

使用者直接訪問控制層,控制層就可以直接操作資料庫;

selvlet--CRUD-->資料庫
弊端:程式十分臃腫,不利於維護
servlet的程式碼中:處理請求、響應,檢視跳轉,處理JDBC、處理業務程式碼、處理邏輯程式碼

架構:沒有什麼是加一層解決不了的!
程式設計師呼叫
|
JDBC
|
Mysql Oracle sqlserver....

10.2、現在

Model

  • 業務處理:業務邏輯(service)
  • 資料持久層: CRUD (Dao)

View

  • 展示資料
  • 提供連線發起Servlet請求 (a, form, img.....)

Controller (Servlet)

  • 接收使用者的請求: (req:請求引數,Session資訊)
  • 交給業務層處理對應的程式碼
  • 控制檢視的跳轉
登入--->接收使用者的登入請求--->處理使用者的請求(獲取使用者登入的引數,username password)--->交給業務層處理登入業務(判斷使用者名稱密碼是否正確:事務)--->Dao層查詢使用者名稱和密碼是否正確--->資料庫

11.Filter

Filter:過濾器,用來過濾網站的資料

  • 處理中文亂碼
  • 登入驗證

Filter開發步驟:

  1. 導包

  2. 編寫過濾器

    1. 導包不要錯

      Filter (javax.servlet)
      
    2. 實現Filter介面,重寫對應的方法

      //初始化:web伺服器啟動,就已經初始化了,隨時等待過濾物件的出現
      public void init(FilterConfig filterConfig) throws ServletException {
      
      }
      
      //Chain:鏈
      /*
          * 1.過濾中的所有程式碼,在過濾特定請求的時候都會執行
          * 2.必須要讓過濾器繼續過濾
          * chain.doFilter(request,response);
          */
      
      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");
      
          filterChain.doFilter(servletRequest,servletResponse);//讓我們的請求繼續走,如果不寫,程式到這裡就會被攔截停止
      }
      
      //銷燬,web伺服器關閉時,過濾就會銷燬
      public void destroy() {
      
      }
      
    3. 在web.xml中配置Filter

      <filter>
          <filter-name>filterencode</filter-name>
          <filter-class>com.lk.filter.filterencode</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>filterencode</filter-name>
          <url-pattern>/filter/*</url-pattern>
      </filter-mapping>
      

12、Listener

實現一個監聽器介面:(有n種)

  1. 編寫一個監聽器

    @Override
        public void sessionCreated(HttpSessionEvent se) {
    
            System.out.println(se.getSession().getId());
            ServletContext sct = se.getSession().getServletContext();
            Integer onlineCounts = (Integer) sct.getAttribute("OnlineCounts");
            if (onlineCounts == null){
                onlineCounts = new Integer(1);
            }else{
                int count = onlineCounts.intValue();
                onlineCounts = new Integer(count+1);
            }
            sct.setAttribute("OnlineCounts", onlineCounts);
            System.out.println(onlineCounts);
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            ServletContext sct = se.getSession().getServletContext();
            Integer onlineCounts = (int) sct.getAttribute("OnlineCounts");
            if (onlineCounts == null){
                onlineCounts = new Integer(0);
            }else{
                int count = onlineCounts.intValue();
                onlineCounts = new Integer(count--);
            }
            sct.setAttribute("OnlineCounts", onlineCounts);
        }
    
  2. web.xml種註冊監聽器

    <listener>
        <listener-class>com.lk.listener.listenertext</listener-class>
    </listener>
    

13、過濾器,監聽器常見應用

監聽器:GUI程式設計中經常使用

使用者登入之後才能進入主頁!使用者登出後就不能進入主頁了!

jsp

  • Login.jsp
  • succeed.jsp
  • error.jsp

servlet

  • login.java
  • unlogin.java

filter

  • sysfilter.java

14、JDBC

14.1、sql

public static void main(String[] args) throws ClassNotFoundException, SQLException {
    //配置資訊
    String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
    String username = "root";
    String password = "123456";
    //1.載入驅動
    Class.forName("com.mysql.jdbc.Driver");
    //2.連線資料庫
    Connection connection = DriverManager.getConnection(url,username,password);
    //3.建立向資料庫傳送SQL的物件Statement
    Statement statement = connection.createStatement();
    //4.編寫SQL
    String sql = "select * from users";
    //5.執行查詢SQL,返回一個結果集
    ResultSet rs = statement.executeQuery(sql);

    while (rs.next()){
        System.out.println("id = "+rs.getObject("id"));
        System.out.println("name = "+rs.getObject("name"));
        System.out.println("password = "+rs.getObject("password"));
        System.out.println("email = "+rs.getObject("email"));
        System.out.println("birthday = "+rs.getObject("birthday"));
    }
    //6.關閉連線,釋放資源(一定要做)
    rs.close();
    statement.close();
    connection.close();
}

14.2、預編譯sql

public static void main(String[] args) throws ClassNotFoundException, SQLException {
    //jdbc引數
    String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
    String username = "root";
    String password = "123456";
    //1.載入驅動
    Class.forName("com.mysql.jdbc.Driver");
    //2.建立連線
    Connection connection = DriverManager.getConnection(url,username,password);
    //3.建立sql語句
    String sql  = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
    //4.預編譯
    PreparedStatement preparedStatement = connection.prepareStatement(sql);

    preparedStatement.setInt(1,9);
    preparedStatement.setString(2,"可可");
    preparedStatement.setString(3,"123132");
    preparedStatement.setString(4,"[email protected]");
    preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));

    //5.執行
    int i = preparedStatement.executeUpdate();
    if (i > 0){
        System.out.println("插入成功!");
    }
    //6.關閉連線
    preparedStatement.close();
    connection.close();
}

14.3、事務:

要麼都成功,要麼都失敗!

ACID原則:保證資料的安全

開啟事務
事務提交 commit()
事務回滾 rollback()
關閉事務

14.4、unit單元測試

//新增上註解就可以直接測試函式,而不必使用main方法
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>
@Test
public void Test(){
    //jdbc引數
    String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
    String username = "root";
    String password = "123456";
    Connection connection = null;

    try {
        //1.載入驅動
        Class.forName("com.mysql.jdbc.Driver");
        //2.建立連線
        connection = DriverManager.getConnection(url,username,password);
        //3.通知資料庫開啟事務, false是開啟
        connection.setAutoCommit(false);
        //4.建立sql語句
        String sql  = "insert into users(id,name,password,email,birthday) values(15,'可楠','123','[email protected]','1999-08-09')";
        //5.執行sql語句
        connection.prepareStatement(sql).executeUpdate();
		//6.製造異常
        System.out.println(1/0);
		//7.事務提交
        connection.commit();
        System.out.println("succeed!");

    } catch (Exception e) {
        try{
            //事務回滾
            connection.rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    } finally {
        try{
            //8.關閉連線
            connection.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}