后端学习 - JavaWeb
生活随笔
收集整理的這篇文章主要介紹了
后端学习 - JavaWeb
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
技術體系
文章目錄
- 一 HTML
- 1 網頁的組成部分
- 2 HTML 概述
- 3 HTML 標簽
- 4 常用標簽
- 5 表單與表單的提交
- 二 CSS
- 1 語法格式
- 2 使用方法
- 三 JavaScript
- 1 概述
- 2 與 HTML 結合的兩種方式
- 3 變量類型及特殊值
- 4 關系、邏輯運算
- 5 數組
- 6 函數
- 7 事件
- 8 DOM (Document Object Model)
- 9 DOM實例:驗證用戶名是否有效
- 四 Tomcat
- 五 Servlet
- 1 舉例:向數據庫中添加表單信息
- 2 Servlet 的繼承關系
- 3 Servlet 的生命周期
- 4 HTTP 協議與 Session會話跟蹤
- 5 服務器端內部轉發、重定向
- 6 Servlet 保存作用域
- 7 Servlet 的 init 方法與初始化參數設置
- 8 ServletContext
- 六 Thymeleaf
- 1 配置過程
- 2 Servlet 優化 - 合并同類方法
- 3 Servlet 優化 - dispatchedServlet
- 七 MVC
- 1 概念
- 2 降低各層間的耦合 - IOC 與 DI
- 3 IOC 與 DI 的實現過程
- 八 Filter
- 1 概述
- 2 使用 Filter 實現事務的原子性
- 九 Listener
- 十 總結
一 HTML
1 網頁的組成部分
- 內容(結構):在頁面中可以看到的數據。我們稱之為內容。一般使用 HTML 技術展示。
- 表現:內容在頁面上的展示形式,比如布局,顏色,大小等等。一般使用CSS 技術實現。
- 行為:頁面中元素與輸入設備交互的響應。一般使用 JavaScript 技術實現。
2 HTML 概述
- Hyper Text Markup Language (超文本標記語言),網頁文件本身是一種文本文件,通過在文本文件中添加標記符,可以告訴瀏覽器如何顯示其中的內容。
- HTML 文件不需要編譯,直接由瀏覽器進行解析執行。
- 書寫規范:大致由 head 和 body 兩部分組成。
3 HTML 標簽
- 標簽名對大小寫不敏感。
- 雙標簽的格式:<標簽名> 封裝的數據 </標簽名>
單標簽的格式:<標簽名/> - 標簽擁有自己的屬性,分為基本屬性和事件屬性。屬性必須有值,屬性值必須加引號。
- 雙標簽必須正確關閉,不能交叉嵌套。
- 想顯示“轉義字符”的問題(比如想打印出左尖括號<),用實體名稱解決(對應的實體名稱是<)。
4 常用標簽
重點是超鏈接、表格、表單
<!--標題標簽,最大是h1,最小是h6,對齊可以選擇 left/ center/ right--> <h1 align="center"> 標題 </h1><!--字體--> <font color="red" size="7"> 字體 </font><!--超鏈接,可選參數 target (_self 在當前頁面跳轉,_blank 在新頁面跳轉...)--> <a href="www.baidu.com" target="_blank"> 超鏈接 </a><!--無序列表(有序將ul改為ol)--> <ul><li> item1 </li><li> item2 </li> </ul><!--圖片img標簽是圖片標簽,用來顯示圖片src屬性可以設置圖片的路徑width屬性設置圖片的寬度height屬性設置圖片的高度border屬性設置圖片邊框大小alt屬性設置當指定路徑找不到圖片時,用來代替顯示的文本內容絕對路徑的正確格式是: http://ip:port/工程名/資源路徑 --> <img src="./imgs/1.jpg" width="100" height="200"/><!--表格table 標簽是表格標簽border 設置表格標簽width 設置表格寬度height 設置表格高度align 設置表格相對于頁面的對齊方式cellspacing 設置單元格間距tr 是行標簽th 是表頭標簽td 是單元格標簽align 設置單元格文本對齊方式b 是加粗標簽如果要實現跨行、跨列,改變 td 的 colspan、rowspan 屬性 --> <table align="center" border="1" width="300" height="300" cellspacing="0"><tr><th>1.1</th><th>1.2</th><th>1.3</th></tr><tr><td>2.1</td><td>2.2</td><td>2.3</td></tr><tr><td>3.1</td><td>3.2</td><td>3.3</td></tr> </table><!--iframe標簽,在原頁面之上顯示一個小的頁面其中的 name 屬性可以作為超鏈接的 target 屬性,點擊超鏈接后將在 iframe 中顯示--> <iframe src="1.html" width="500" height="400" name="abc"></iframe> <a href="2.html" target="abc"> 超鏈接 </a>5 表單與表單的提交
表單類型單獨列出,可以使用 table 實現對齊。
<!-- 要順利提交表單,需要為所有項加上 value 或者 name 屬性 --><form action="http://localhost:8080" method="post">姓名:<input type="text" value="默認姓名"/></br>密碼:<input type="password" value="default"/></br><!-- name 屬性用于分組,同一組的選項互斥-->性別:<input type="radio" name="sex" checked="checked"/>男 <input type="radio" name="sex"/>女</br>愛好:<input type="checkbox" checked="checked"/>跑步 <input type="checkbox"/>跳繩</br>國籍:<select><option>--請選擇--</option><option selected="selected">CHN</option><option>USA</option></select><br/>簡介:<textarea rows="10" cols="20">默認簡介</textarea><br/>附件:<input type="file"/></br><input type="reset" value="重置"><input type="submit" value="提交"></form>- form 標簽的 action 屬性設置提交的服務器地址,method 屬性設置提交的方式 GET(默認) 或 POST
- GET 請求的特點是:
- 瀏覽器地址欄中的地址是:服務器地址 + ? + 請求參數(請求參數的格式是 name=value&name=value)
- 不安全
- 有數據長度的限制
- POST 請求的特點:
- 瀏覽器地址欄中只有服務器地址(action的屬性值)
- 相對于GET請求要安全
- 理論上沒有數據長度的限制
- 表單提交的時候,數據沒有發送給服務器的三種情況:
- 表單項沒有name屬性值
- 單選 radio 、復選 checkbox、下拉列表中的 option 標簽 都需要添加value屬性,以便發送給服務器
- 表單項不在提交的form標簽中
二 CSS
1 語法格式
/* 標簽名選擇器,樣式綁定標簽 */ label_name { property1: val1;property2: val2; }/* id選擇器,樣式綁定具體的id,id是人為設定的,每個實例不相同*/ #id {property1: val1;property2: val2; }/* class選擇器,樣式綁定標簽分配的class,可以多個實例綁定一個class */ .class class_name {property1: val1;property2: val2; }/* 組合選擇器,選擇器間是并的關系 */ 選擇器1, 選擇器2 ... {property1: val1;property2: val2; }2 使用方法
<head> <!-- HEAD --><meta charset="UTF-8"><title> my_title </title>/* 導入已經寫好的CSS文件(推薦) */<link rel="stylesheet" type="text/CSS" href="mycss.css">/* 或者把CSS寫到此處的 style 標簽中 */<style type="text/css">label_name { property1: val1;property2: val2;}</style></head>三 JavaScript
1 概述
- JS 運行在客戶端,需要運行瀏覽器來解析執行 JavaScript 代碼,和 Java 并無直接關系。
- JS 是弱類型的語言,Java 是強類型的語言。強弱的差別在于定義變量后,變量的數據類型是否可變。
- 特點是 交互性(信息的動態交互)、安全性(不允許直接訪問本地硬盤)、跨平臺性(只要是可以解釋 JS 的瀏覽器都可以執行,和平臺無關)。
2 與 HTML 結合的兩種方式
- 在 HTML 文件中的 head 部分,用 script 標簽寫入;
- 在 script 標簽中導入 JS 文件。
上述兩種方法不能寫在一個標簽里。
<head><meta charset="UTF-8"><title>Title</title><script type="text/javascript">alert('JS嵌入方式1');</script><script src="myjs.js"></script> <!-- 文件內容: alert('JS嵌入方式2'); --> </head>3 變量類型及特殊值
| number | 數值類型 |
| string | 字符串類型 |
| object | 對象類型 |
| bool | 布爾類型 |
| function | 函數類型 |
| undefined | 未定義,所有 JS 變量未賦于初始值的時候,默認值都是 undefined |
| null | 空 |
| NaN | 非數字非數值 |
4 關系、邏輯運算
- ==比較兩個變量的值是否相等(比如,“123”==123是成立的), ===比較兩個變量的類型和值是否相等;
- JS 中所有變量都可以作為布爾值使用,0、null、undefined、空串 都認為是 false;
- ||(或) &&(與) 具有短路特性,返回值為第一個導致結果的變量。
5 數組
- 數組不會出現越界的問題。在超過原來長度的位置賦值時,會進行自動擴容(讀操作不會擴容)。
6 函數
- JS 不允許函數重載。一個函數名只能對應一個具體實現。
- 隱形參數 arguments 將所有實參組織為一個數組,通過下標可以訪問所有參數。
7 事件
- 常用事件
| onload(加載完成) | 常用做頁面 JS 代碼初始化操作 |
| onclick(單擊) | 按鈕的點擊響應操作 |
| onblur(失去焦點) | 輸入框失去焦點后驗證其輸入內容是否合法 |
| onchange(內容發生改變) | 下拉列表和輸入框內容發生改變后操作 |
| onsubmit(表單提交) | 表單提交前,驗證所有表單項是否合法 |
- 事件需要進行注冊才能使用:
- 靜態注冊:通過 HTML 標簽的事件屬性,直接賦于事件響應后的代碼;
- 動態注冊:先通過 JS 代碼得到標簽的 dom 對象,然后再通過 dom 對象.事件名 = function(){} 這種形式賦于事件響應后的代碼。
- onload 事件
- onclick 事件
- onblur 事件(同上)
- onchange 事件,綁定的是 select 而非 option 標簽
- onsubmit 事件,綁定的是表格而非按鈕,返回 false 則不會提交表單
8 DOM (Document Object Model)
- 簡單來說,將整個 HTML 文件視為一個 document 對象,并把其中所有的標簽對象化,形成了樹型結構。
- document 實例提供查詢方法,使用優先級從高到低:getElementByID(返回一個實例),getElementByName(可以數組形式返回多個實例),getElementByTagName(以數組形式返回指定標簽的對象)。注意:頁面加載完之后才能進行查詢!不僅限于放在 onload 事件中。
- document 實例提供創建方法:createElement
9 DOM實例:驗證用戶名是否有效
限制用戶名由數字和字母組成,長度區間為 [5, 12]
<html lang="en"> <head><meta charset="UTF-8"><title>Title</title><script>window.onload = function () {var tip = document.getElementById("tip");var btn = document.getElementById("btn");var text = document.getElementById("text");btn.onclick = function () {var input = text.value;var pattern = /^\w{5,12}$/;if (pattern.test(input)) { <!-- 匹配正則表達式 -->tip.innerHTML = "通過"; <!-- innerHTML 返回的是開始和結束標簽之間的值,可讀寫-->} else {tip.innerHTML = "不通過";}}}</script> </head> <body> <input type="text" id="text"> <span id="tip" style="color: brown"></span> <button id="btn">檢查</button> </body> </html>四 Tomcat
- 簡單來說,Tomcat 就是一個運行JAVA的網絡服務器。
- HTML 文件通過本地訪問,使用的協議是 file,執行的操作是直接獲取并解析;
- IDEA 2021.3.1 創建JavaWeb工程的方法
- 通過WEB服務器訪問,使用的協議是 http,經過了客戶端請求與服務器響應的過程,執行操作如下圖:
五 Servlet
1 舉例:向數據庫中添加表單信息
一種方式是使用 web.xml 配置(另一種是通過在 AddServlet 注釋 @WebServlet("/add") ):
2 Servlet 的繼承關系
- 繼承關系: HttpServlet 具體實現類 -> GenericServlet 抽象類 -> Servlet 接口
- Servlet中的核心方法:service()
- 當收到請求,service 方法會自動響應(tomcat 容器調用),在 HttpServlet 中分析請求的方式:到底是get、post、head 等等,然后再決定調用具體的 doXX 的方法。
- 在 HttpServlet 中,doXX 方法默認都是405(報錯信息是找不到方法實現),除非子類去實現對應的 doXX 方法,否則默認會報405錯誤。
3 Servlet 的生命周期
- 三個重要的方法:init、service、destory
- 默認情況下, 第一次接收請求時,Servlet 會進行實例化(調用構造方法)、初始化(調用init())、然后服務(調用service());從第二次請求開始,每一次都是服務(調用service());當容器關閉時,其中的所有的 Servlet 實例會被銷毀(調用destroy())。
- 如果需要提高響應速度,應該設置 Servlet 的初始化時機,在第一次請求之前執行實例化和初始化。具體做法是,在 web.xml 中的 <servlet> 中添加 <load-on-startup> 標簽。
- Servlet 是單例的、線程不安全的。單例是指,對于一個確定的 Servlet 類型,所有的請求都是同一個 Servlet 實例去響應;由于 Servlet 線程不安全,所以盡量避免在其中設置成員變量,如果設置盡量不要讀寫。
4 HTTP 協議與 Session會話跟蹤
- HTTP 協議是無狀態的,需要通過會話跟蹤技術保存用戶的歷史信息。
- HTTP 請求與響應報文的格式略。
- 常用的API:
request.getSession() -> 獲取當前的會話,沒有則創建一個新的會話
request.getSession(true) -> 效果和不帶參數相同
request.getSession(false) -> 獲取當前會話,沒有則返回null,不會創建新的
session.getId() -> 獲取sessionID
session.isNew() -> 判斷當前session是否是新的
session.getMaxInactiveInterval() -> session的非激活間隔時長,默認1800秒
session.setMaxInactiveInterval()
session.invalidate() -> 強制讓會話立即失效
5 服務器端內部轉發、重定向
-
服務器端內部轉發對客戶端是不可見的,執行方法:request.getRequestDispatcher("...").forward(request, response)
-
重定向對客戶端可見,并且會顯示地更改 URL,執行方法:response.sendRedirect("...")
6 Servlet 保存作用域
7 Servlet 的 init 方法與初始化參數設置
- 兩種 init 方法:
如果需要進行一些初始化操作,重寫無參的 init 方法
- 初始化參數設置
- 讀取初始化參數:
8 ServletContext
- ServletContext是一個全局的儲存信息的空間,服務器開始就存在,服務器關閉才釋放(application級別)
- 類似 session,可以想象成一個 map
- 多個Servlet可以通過ServletContext對象來實現數據間的共享,如果是涉及到不同用戶共享數據,而這些數據量不大,同時又不希望寫入數據庫中,我們就可以考慮使用 ServletContext 實現
- 初始化 ServletContext 時,不能寫在具體的某個 servlet 標簽中,因為它是全局的
六 Thymeleaf
1 配置過程
邏輯視圖名稱 : index
物理視圖名稱 : view-prefix + 邏輯視圖名稱 + view-suffix
真實的視圖名稱: / index .html
2 Servlet 優化 - 合并同類方法
- 之前的一個 Servlet 只提供一種方法,此處的改進是將同類的多種方法合并到一個 Servlet 中
- 使用反射代替 switch-case
3 Servlet 優化 - dispatchedServlet
- 相當于一個 meta 的 Servlet,稱為 DispatchedServlet,繼承自 ViewBaseServlet。合并所有種類的 Servlet,并將原來的 Servlet 轉為 Controller,剝奪其注釋 @WebServlet
- 在 src 目錄下創建 applicationContext.xml,利用 bean 標簽,為參數名和 Controller 建立映射
- DispatchedServlet 的 init 方法根據 xml 配置 Map<String,Object> beanMap
- 使用時,向 DispatchedServlet 傳遞參數,由其 service 方法負責解析,并根據 beanMap 調用指定的 Controller,具體步驟:
- 獲取參數:獲取即將要調用的方法的參數簽名信息
- 執行方法:Object returnObj = method.invoke(controllerBean , parameterValues);
- 視圖處理:根據返回值調用重定向等 String returnStr = (String)returnObj; if(returnStr.startWith("redirect:")){ .... } else if.....
七 MVC
1 概念
- MVC(Model–View–Controller)模式是軟件工程中的一種軟件架構模式,它把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。
- Controller 作為 Model 和 View 部分的“膠水”,本身不適合包含太多的邏輯。
2 降低各層間的耦合 - IOC 與 DI
- DI(Dependency Injection,依賴注入)是 IOC(Inversion of Control,控制反轉)最常用的方法。
- IOC 是一種設計思想,核心是,將設計好的對象交給容器控制,而不是傳統的在對象內部直接控制。 把創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,所以對象與對象之間是松散的耦合。
- Spring 所倡導的開發方式就是如此,所有的類都會在 spring 容器中登記,告訴 spring 你是個什么東西,你需要什么東西,然后 spring 會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其他需要你的東西。所有的類的創建、銷毀都由 spring 容器來控制,也就是說控制對象生存周期的不再是引用它的對象,而是 spring。對于某個具體的對象而言,以前是它控制其他對象,現在是所有對象都被 spring 控制,所以這叫控制反轉。
- IOC 容器實際上就是 map(key,value),里面存的是各種對象(在 xml 里配置的 bean 節點、service、controller、component),在項目啟動的時候會讀取配置文件里面的 bean 節點,根據全限定類名使用反射創建對象并放到 map 里。
通過 IOC 容器,上述過程轉為:
- IoC的一個重點是在系統運行中,動態的向某個對象提供它所需要的其他對象。這一點是通過 DI 來實現的。在類中需要使用到的對象,全部通過反射從第三方容器注入而不是自己創建。
- 比如對象A需要操作數據庫,以前我們總是要在A中自己編寫代碼來獲得一個 Connection 對象,有了 spring 只需要告訴 spring ,A中需要一個 Connection,至于這個 Connection 怎么構造,何時構造,A不需要知道。在系統運行時,spring 會在適當的時候制造一個 Connection,然后像打針一樣,注射到A當中,這樣就完成了對各個對象之間關系的控制。A需要依賴 Connection 才能正常運行,而這個 Connection 是由 spring 注入到A中的,依賴注入的名字就這么來的。
3 IOC 與 DI 的實現過程
BeanFactory 實現:
public class ClassPathXmlApplicationContext implements BeanFactory {private Map<String,Object> beanMap = new HashMap<>();public ClassPathXmlApplicationContext(){try {InputStream inputStream = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");//1.創建DocumentBuilderFactoryDocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();//2.創建DocumentBuilder對象DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder() ;//3.創建Document對象Document document = documentBuilder.parse(inputStream);//4.獲取所有的bean節點NodeList beanNodeList = document.getElementsByTagName("bean");for(int i = 0 ; i<beanNodeList.getLength() ; i++){Node beanNode = beanNodeList.item(i);if(beanNode.getNodeType() == Node.ELEMENT_NODE){Element beanElement = (Element)beanNode ;String beanId = beanElement.getAttribute("id");String className = beanElement.getAttribute("class");Class beanClass = Class.forName(className);//創建bean實例Object beanObj = beanClass.newInstance() ;//將bean實例對象保存到map容器中beanMap.put(beanId , beanObj) ;//到目前為止,此處需要注意的是,bean和bean之間的依賴關系還沒有設置}}//5.組裝bean之間的依賴關系for(int i = 0 ; i<beanNodeList.getLength() ; i++){Node beanNode = beanNodeList.item(i);if(beanNode.getNodeType() == Node.ELEMENT_NODE) {Element beanElement = (Element) beanNode;String beanId = beanElement.getAttribute("id");NodeList beanChildNodeList = beanElement.getChildNodes();for (int j = 0; j < beanChildNodeList.getLength() ; j++) {Node beanChildNode = beanChildNodeList.item(j);if(beanChildNode.getNodeType()==Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())){Element propertyElement = (Element) beanChildNode;String propertyName = propertyElement.getAttribute("name");String propertyRef = propertyElement.getAttribute("ref");//1) 找到propertyRef對應的實例Object refObj = beanMap.get(propertyRef);//2) 將refObj設置到當前bean對應的實例的property屬性上去Object beanObj = beanMap.get(beanId);Class beanClazz = beanObj.getClass();Field propertyField = beanClazz.getDeclaredField(propertyName);propertyField.setAccessible(true);propertyField.set(beanObj,refObj);}}}}} catch (ParserConfigurationException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();}}@Overridepublic Object getBean(String id) {return beanMap.get(id);} }八 Filter
1 概述
- 繼承自 Filter 類,具有 init, doFilter, destory 方法
- 可以使用注解的形式 @WebFilter("fruit.do"),也可以在 web.xml 中配置
- 使用注解形式,當具有多個 Filter 時,按照類名的字典序組織過濾順序
2 使用 Filter 實現事務的原子性
- 利用 Filter 的機制,在放行之前撤銷 conn 的自動提交,在返回時手動執行提交,并在捕獲到異常時執行回滾
- 要求事務執行的過程中,遇到的異常要層層向外拋出,直到被 Filter 捕獲,而不是就地解決
- 將 conn 綁定 ThreadLocal 實例,再進一步保存到 ThreadLocalMap 中,保證了多個 DAO 共用同一個數據庫連接,不會因為連接的關閉而自動提交,破壞事務的原子性
九 Listener
- 監聽某個組件的某種行為,當這種行為被監聽到時,調用指定的方法
- 可以用于完成初始化的創建,以及結束時的銷毀操作
- 一個應用實例:IOC 容器的 beanMap,當監聽到 ServletContext 對象創建時,在監聽器內進行初始化,而非在 Servlet 的 init 方法中完成
十 總結
總結
以上是生活随笔為你收集整理的后端学习 - JavaWeb的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信如何拉黑别人
- 下一篇: java中file_详细介绍Java中的