01-原生Java開發(fā)


1、分層結(jié)構(gòu)

目的:實現(xiàn)應(yīng)用程序的模塊化和解耦,便于團隊協(xié)作和維護。
?1. 控制層(Controller):控制層主要負責處理用戶請求和響應(yīng)
?2. 服務(wù)層(Service):服務(wù)層主要負責業(yè)務(wù)邏輯的處理。
?3. 數(shù)據(jù)訪問層(DAO):數(shù)據(jù)訪問層主要負責與數(shù)據(jù)庫進行交互。


分層結(jié)構(gòu).png

2、使用技術(shù)

Java原生開發(fā).png

2.1、 控制層(Controller):

Servlet 是 Java Web 應(yīng)用程序的基礎(chǔ),它提供了一種用于處理 HTTP 請求的標準 Java 接口,每個 Servlet 類處理特定的請求。在早期的 Web 開發(fā)中,Servlet 是一種主流的解決方案。

2.1.1、 Servlet的工作模式

  1. 客戶端發(fā)送請求至服務(wù)器

  2. 服務(wù)器運行并調(diào)用Servlet,Servlet根據(jù)客戶端請求生成響應(yīng)內(nèi)容并將其傳給服務(wù)器,響應(yīng)內(nèi)容動態(tài)生成,通常取決于客戶端的請求

  3. 服務(wù)器將響應(yīng)返回客戶端

出自CSDN博主「atCarl」的原創(chuàng)文章,原文鏈接:https://blog.csdn.net/2201_75955594/article/details/130232573

2.1.2、 Servlet的生命周期

Servlet的生命周期是由容器管理的,Servlet容器(例如Tomcat)會根據(jù)下面的規(guī)則來調(diào)用這三個方法:

  1. 初始化方法init( ),只會執(zhí)行一次(啟動Tomcat的時候默認是不執(zhí)行的,在訪問的時候才會執(zhí)行)當Servlet第一次被請求時,Servlet容器會實例化這個Servlet,然后就會調(diào)用這個方法來初始化Servlet,但是這個方法在后續(xù)請求中不會在被Servlet容器調(diào)用,我們可以利用init()方法來執(zhí)行相應(yīng)的初始化工作。

  2. 服務(wù)方法service( ),每當請求Servlet時,Servlet容器就會調(diào)用這個方法。第一次請求時,Servlet容器會先調(diào)用init( )方法初始化一個Servlet對象出來,然后會調(diào)用它的service( )方法進行工作,但在后續(xù)的請求中,Servlet容器只會調(diào)用service方法了。
    service()方法根據(jù)請求的類型(Get、Post等)調(diào)用相應(yīng)的doGet()、doPost()等方法
    要么重寫doGet、doPost ,要么重寫 service,必須二選一,而且必須進行重寫。

  3. 銷毀方法destory(),當要銷毀Servlet時,Servlet容器就會調(diào)用這個方法,卸載應(yīng)用程序或者關(guān)閉Servlet容器時,就會發(fā)生這種情況,一般在這個方法中會寫一些清除代碼。

參考CSDN博主「atCarl」的原創(chuàng)文章,原文鏈接:https://blog.csdn.net/2201_75955594/article/details/130232573

2.1.3、 Servlet的開發(fā)步驟

1.導入 jar 包【servlet】

 <!--tomcat依賴 內(nèi)含tomcat-servlet-api-->
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-api</artifactId>
      <version>8.5.41</version>
      <scope>provided</scope>
    </dependency>
或者
<!--servlet-api-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
</dependency>

2.創(chuàng)建一個 Servlet類


3.在web容器中注冊 servlet【配置Servlet】
一般有兩種方式:web.xml / 注解(Servlet 3.0 開發(fā)人員可以使用注解的方式配置Servlet)

4.寫一個 jsp 頁面(此處忽略)

5.處理邏輯并響應(yīng)請求


參考知乎作者[JasonWX]的原創(chuàng)文章,原文鏈接:https://zhuanlan.zhihu.com/p/591105720?utm_id=0


2.1.4、 Servlet之Filter(過濾器)

Filter(過濾器):過濾器可以動態(tài)地攔截請求和響應(yīng),以變換或使用包含在請求或響應(yīng)中的信息,也就是說可以監(jiān)視,修改或以某種方式處理客戶端與服務(wù)端下在交流的數(shù)據(jù)。


(1)在客戶端的請求訪問后端資源之前,攔截這些請求。例如靜態(tài)資源或登錄、注冊、驗證碼等資源放行,其他資源攔截
(2)在服務(wù)器的響應(yīng)發(fā)送回客戶端之前,處理這些響應(yīng)。亂碼的統(tǒng)一處理、過濾非法字符、對非法的請求進行攔截(權(quán)限校驗)

過濾器的生命周期:
1)服務(wù)器啟動時實例化過濾器
2)調(diào)用init()方法初始化參數(shù)
3)利用FilterConfig ->getInitParams(name)方法獲取參數(shù)值
4)客戶端請求數(shù)據(jù)時doFilter()執(zhí)行過濾器
5)服務(wù)器關(guān)閉時容器銷毀過濾器實例前調(diào)用destory()方法

過濾器的開發(fā)步驟
1)創(chuàng)建一個類實現(xiàn)javax.servlet.Filter接口
2)重寫接口中所有的方法,其中有doFilter方法,用來執(zhí)行過濾的任務(wù)。有請求和響應(yīng)兩個參數(shù)
3)注冊過濾器在 web.xml中進行配置 或者 通過注解的方式:@WebFilter("過濾的地址")

過濾器代碼示意圖


2.1.5、 Servlet之Listener(監(jiān)聽器)

Listener(監(jiān)聽器):
用于監(jiān)聽web應(yīng)用中某些對象、信息的創(chuàng)建、銷毀、增加,修改,刪除等動作的發(fā)生,然后作出相應(yīng)的響應(yīng)處理。當范圍對象的狀態(tài)發(fā)生變化的時候,服務(wù)器自動調(diào)用監(jiān)聽器對象中的方法。常用于統(tǒng)計在線人數(shù)和在線用戶,系統(tǒng)加載時進行信息初始化,統(tǒng)計網(wǎng)站的訪問量等等。

特點:
1)監(jiān)聽方法中的邏輯代碼由程序員根據(jù)需要編寫
2)監(jiān)聽方法由tomcat根據(jù)監(jiān)聽結(jié)果來調(diào)用執(zhí)行

相關(guān)概念:
事件源:被監(jiān)聽的對象(三個域?qū)ο?request、session、servletContext)
監(jiān)聽器:監(jiān)聽事件源對象事件源對象的狀態(tài)的變化都會觸發(fā)監(jiān)聽器
注冊監(jiān)聽器:將監(jiān)聽器與事件源進行綁定
響應(yīng)行為:監(jiān)聽器監(jiān)聽到事件源的狀態(tài)變化時所涉及的功能代碼(程序員編寫代碼)

監(jiān)聽器的類別:

在JavaWEB中,監(jiān)聽器分為三大類:

對象類型 作用范圍 生命周期
ServletContext (應(yīng)用域、上下文域) 所有用戶的所有請求 服務(wù)器關(guān)閉時結(jié)束
HttpSession(會話域) session銷毀之前 默認30分鐘
HttpServletRequest(請求域) 一個用戶的一次請求 每次請求就結(jié)束

八大種:
1)監(jiān)聽域?qū)ο?/strong>需要在web.xml中配置

對象類型 對應(yīng)的監(jiān)聽器 作用
ServletContext ServletContextListener 監(jiān)聽ServletContext的生命周期
HttpSession HttpSessionListener 監(jiān)聽Session的生命周期
HttpServletRequest ServletRequestListener 監(jiān)聽Request的生命周期

2)監(jiān)聽屬性需要在web.xml中配置

對象類型 對應(yīng)的監(jiān)聽器 作用
ServletContext ServletContextAttributeListener 監(jiān)聽ServletContext屬性的變化
HttpSession HttpSessionAttributeListener 監(jiān)聽Session屬性的變化
HttpServletRequest ServletRequestAttributeListener 監(jiān)聽Request屬性的變化

3)監(jiān)聽session對象狀態(tài)不需要在web.xml中配置

對象類型 對應(yīng)的監(jiān)聽器 作用
HttpSession HttpSessionBindingListener(綁定,解除綁定) 監(jiān)聽session的屬性綁定與移除
HttpSession HttpSessionActivationListener(鈍化和活化) 監(jiān)聽session中的屬性鈍化與活化

(一)鈍化:當服務(wù)器正常關(guān)閉時,還存活著的session(在設(shè)置時間內(nèi)沒有銷毀) 會隨著服務(wù)器的關(guān)閉被以文件(“SESSIONS.ser”)的形式存儲在tomcat 的work 目錄下,這個過程叫做Session 的鈍化。
(二)活化:當服務(wù)器再次正常開啟時,服務(wù)器會找到之前的“SESSIONS.ser” 文件,從中恢復之前保存起來的Session 對象,這個過程叫做Session的活化。

監(jiān)聽器的開發(fā)步驟
1)實現(xiàn)對應(yīng)的接口
2)重寫接口中的方法
3)在web.xml中注冊該listener(根據(jù)監(jiān)聽器類型判斷需不需要)

參考CSDN博主「猿小許」的原創(chuàng)文章,原文鏈接:https://blog.csdn.net/weixin_44205087/article/details/117923765


2.1.6、 請求轉(zhuǎn)發(fā)和請求重定向

轉(zhuǎn)發(fā)與重定向?qū)崿F(xiàn)的功能是相同的,用于從一個頁面跳轉(zhuǎn)到另一個頁面。但是從內(nèi)部細節(jié)上有很大的不同。
請求轉(zhuǎn)發(fā)(forward):發(fā)生在服務(wù)端程序內(nèi)部,由服務(wù)器進行的頁面跳轉(zhuǎn),因此也叫服務(wù)器內(nèi)部轉(zhuǎn)發(fā);當服務(wù)器端收到一個客戶端的請求之后,會先將請求轉(zhuǎn)發(fā)給目標地址,再將目標地址返回的結(jié)果轉(zhuǎn)發(fā)給客戶端, 而客戶端對于這一切毫無感知的。
轉(zhuǎn)發(fā)的特點:
1)轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部的行為,因此在轉(zhuǎn)發(fā)時,客戶端請求的地址不會發(fā)生變化,即使服務(wù)器內(nèi)部已經(jīng)跳轉(zhuǎn)了好幾次了,但是客戶端訪問的地址依舊不變;
2)整個轉(zhuǎn)發(fā)過程中,客戶端從始至終只發(fā)送了一次請求;
3)由于在整個轉(zhuǎn)發(fā)過程中,客戶端只發(fā)送了一次請求,因此請求域的數(shù)據(jù)不會失效;
4)轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部的行為,因此我們不需要加上項目名;例如:request.getRequestDispatcher("/demo01")
轉(zhuǎn)發(fā)示例:客戶端訪問資源/demo01,服務(wù)器發(fā)現(xiàn)客戶端想要的資源不在/demo01于是自己將請求轉(zhuǎn)發(fā)到/demo02,這個過程客戶端無感知;客戶端只請求了一次;

請求轉(zhuǎn)發(fā)圖解

請求重定向:服務(wù)器端接收到客戶端的請求之后,會給客戶端返回了一個臨時響應(yīng)頭,這個臨時響應(yīng)頭中記錄了客戶端需要再次發(fā)送請求(重定向)的 URL 地址,客戶端根據(jù)服務(wù)器反饋的信息再次請求服務(wù)器,這就是請求重定向。
重定向的特點:
1)由于客戶端重定向是客戶端再次請求,因此客戶端的地址欄的地址已經(jīng)發(fā)生了變化;
2)客戶端請求了兩次服務(wù)器
3)在整個重定向過程中,客戶端發(fā)送了兩次請求,請求域中的數(shù)據(jù)丟失;
4)重定向是客戶端行為(客戶端再次請求),我們需要加上項目名;例如:sendRedirect("request.getContextPath()+/demo01")
如果需要保留請求域中的數(shù)據(jù),使用轉(zhuǎn)發(fā),否則使用重定向。
重定向示例:客戶端首先訪問資源/demo01,服務(wù)器發(fā)現(xiàn)想要的資源不在demo01這里,于是告訴(sendRedirect)客戶端:"你要的資源不在我這里,你去訪問/demo02"吧!于是客戶端再次訪問資源/demo02;在重定向中,客戶端已經(jīng)請求了兩次服務(wù)器。

請求重定向圖解


2.2、服務(wù)層(Service):

開發(fā)人員主動管理對象。


2.3、 數(shù)據(jù)訪問層(DAO):

Java Database Connectivity,簡稱JDBC;是Java語言中用來規(guī)范客戶端程序如何來訪問數(shù)據(jù)庫的應(yīng)用程
序接口,提供了諸如查詢和更新數(shù)據(jù)庫中數(shù)據(jù)的方法。

2.3.1、 JDBC的優(yōu)點:

  1. JDBC API是一組接口,沒有具體的實現(xiàn)。實現(xiàn)類由各數(shù)據(jù)庫廠商去實現(xiàn)。只需要調(diào)用接口中
    的方法即可。
  2. JDBC代碼只需要少量的修改就可以訪問另一種數(shù)據(jù)庫。
  3. 所有數(shù)據(jù)庫框架,底層最終都會轉(zhuǎn)成JDBC的代碼來實現(xiàn)。

2.3.2、 JDBC的操作步驟

2.3.2.1、 加載驅(qū)動

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

2.3.2.2、 獲得連接

//數(shù)據(jù)庫連接信息,一般配置在.properties文件中
String url = "jdbc:mysql://localhost:3306/project_db?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC";
String username= "root";
String password= "abc1234.";
//獲取連接
Connection con = DriverManager.getConnection(url, username, password);

2.3.2.3、 執(zhí)行指令

PreparedStatement ps = con.prepareStatement("select * from studernt");

2.3.2.4、 獲取查詢結(jié)果集(查詢才有,增刪無此步驟)

List<Student> list=new ArrayList<Student>();
rs=ps.executeQuery();
while (rs.next()) {
    Student stu=new Student();
    stu.setId(rs.getInt(1));
    stu.setName(rs.getString(2));
    stu.setAge(rs.getInt(3));
    stu.setBirthday(rs.getDate(4));
    list.add(stu); 
}

2.3.2.5、 關(guān)閉資源

if(con!=null&&!con.isClosed()) {
    con.close();
}
if(ps!=null) {
    ps.close();
}

參考CSDN博主「LJT_1314520」的原創(chuàng)文章,原文鏈接:https://blog.csdn.net/LJT_1314520/article/details/125241649

2.3.3、 SQL注入問題

Statement是先在sql語句中傳值再編譯,存在sql注入問題。
PreparedStatement是先對sql語句進行預(yù)編譯,然后再傳入變量值,預(yù)編譯中的待傳參數(shù)部分用?占位符代替。解決了sql注入

2.3.4、 連接池

原因:每次訪問數(shù)據(jù)庫都必須先創(chuàng)建連接,執(zhí)行完畢以后關(guān)閉連接對象。連接對象需要不停的創(chuàng)建,不停的關(guān)
閉。

問題:
1)數(shù)據(jù)庫創(chuàng)建連接通常需要消耗相對較多的資源,創(chuàng)建時間也較長,而每次操作都要重新獲取新的
連接對象,執(zhí)行一次操作就把連接關(guān)閉,這樣數(shù)據(jù)庫連接對象的使用率低。
2)假設(shè)網(wǎng)站一天10萬訪問量,數(shù)據(jù)庫服務(wù)器就需要創(chuàng)建10萬次連接,極大的浪費數(shù)據(jù)庫的資源,并
且極易造成數(shù)據(jù)庫服務(wù)器內(nèi)存溢出。

連接對象 操作特點
創(chuàng)建時 程序啟動的時候,由應(yīng)用程序在內(nèi)存中創(chuàng)建好一定數(shù)量的連接對象,放在內(nèi)存中,這個內(nèi)存區(qū)域就稱為連接池,也叫數(shù)據(jù)源DataSource 。
使用時 訪問數(shù)據(jù)庫的時候,直接從連接池中得到一個連接對象就可以了。
關(guān)閉時 不是真的關(guān)閉連接,而是將連接對象再放回到連接池中,給下一個用戶使用。

作用:
1)提高獲取連接對象的速度;
2)提高連接對象的使用率,每個連接對象可以重復使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容