日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

初学Java Web(4)——Servlet学习总结

發(fā)布時間:2025/3/21 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初学Java Web(4)——Servlet学习总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

經(jīng)過一段時間的學習,對于Servlet有了新的不一樣的見解,在這里做一下總結(jié),將近來學習到的知識總結(jié)一下。


Servlet 的請求流程

  • 瀏覽器發(fā)出請求:http://localhost:80/xxx1/xxx2 (80端口可以默認不寫,因為這是http協(xié)議默認的端口,平時我們訪問https://www.baidu.com/ 時其實訪問的是https://www.baidu.com:80/)

  • 服務器解析請求信息:
    • http:協(xié)議名稱
    • localhost:訪問的是互聯(lián)網(wǎng)中的哪一臺計算機
    • 80:從主機當中找到對應 80 端口的程序?這里即為 Tomcat 服務器
    • /xxx1:當前項目的上下文路徑?(即在 server.xml 中配置主機時配置的?path屬性
    • /xxx2:當前請求的資源名
  • 解析?Tomcat 服務器根目錄下的?/config/server.xml?文件:
    <Context docBase="D:\javaPros\test\webapp" path="xxx1" />
    判斷哪一個<Context />元素的?path屬性?屬性為?xxx1
    • 若找不到,則返回?404錯誤
    • 若找到了,則解析該<Context />元素,得到docBase屬性,獲取當前訪問 Web 項目的跟的絕對路徑:D:\javaPros\test\webapp
  • 從D:\javaPros\test\webapp下的?WEB-INF?下找到?web.xml?文件
    判斷?web.xml?文件中是否有?<url-pattern>?的文本內(nèi)容為?/xxx2
    • 若找不到,則返回?404錯誤
    • 若找到了,則繼續(xù)獲取該資源對應 Servlet 類的全限名稱:?xxx.xxx
  • 判斷?Servlet 實例緩存池?中是否有 xxx.xxx 的對象
  • Map<String,Servlet> cache = ......(Tomcat提供的);key:存Servlet類的全限定名稱value:該Servlet類的對象. Servlet obj = cache.get("xxx.xxx");if(obj==null){//Servlet實例緩存中沒有該類的對象,第一次.GOTO 6:}else{//有對象,非第一次.GOTO 8:} }
  • 使用反射調(diào)用構(gòu)造器,創(chuàng)建對應的對象
    obj = Class.forName("xxx.xxx").newInstance();
    把當前創(chuàng)建的?Servlet 對象,存放在緩存之中,供給下一次的使用.
    cache.put("xxx.xxx",obj);

  • 創(chuàng)建?ServletConfig 對象,并調(diào)用?init()?方法
    obj.init(config);

  • 創(chuàng)建?ServletRequest 對象和 ServletResponse 對象,并調(diào)用?service()方法
    obj.service(req,resp);

  • 在?service()?方法中對瀏覽器作出響應操作。


  • Servlet 生命周期

    在 Web 容器中,Servlet 主要經(jīng)歷 4 個階段,如下圖:

  • 加載 Servlet:當 Tomcat?第一次訪問 Servlet?的時候,Tomcat 會負責創(chuàng)建 Servlet 的實例。
  • 初始化 Servlet:當 Servlet 被實例化之后,Tomcat 會調(diào)用?init()?方法來初始化這個對象。
  • 處理服務:當瀏覽器訪問 Servlet?的時候,Servlet 會調(diào)用?service()?方法處理請求。
  • 銷毀:當?Tomcat 關閉或者檢測到 Servlet 要從 Tomcat 刪除的時候,會自動調(diào)用?destroy()?方法,讓該實例所占用的資源釋放掉。一個 Servlet 如果長時間不被使用的話,也會被 Tomcat 自動銷毀。
    • 簡單總結(jié):只要訪問 Servlet ,就會調(diào)用其對應的?service()?方法,init()?方法只會在第一次訪問 Serlvet 的時候才會被調(diào)用。

    這一部分參考文章:這里是鏈接


    Servlet 提供處理請求的方法

    前面的文章里面提到過,廣義上,Servlet?即實現(xiàn)了?Servlet 接口?的類,當我們創(chuàng)建一個自定義類,實現(xiàn)?Servlet 接口?的時候,會發(fā)現(xiàn)有 5 個方法需要重寫,有init【初始化】,destroy【銷毀】,service【服務】,ServletConfig【Servlet配置】,getServletInfo【Serlvet信息】。

    這樣做的話,我們每次都需要實現(xiàn) 5 個方法,太麻煩了!

    我們可以直接繼承 HttpServlet?類,該類已經(jīng)默認實現(xiàn)了 Servlet 接口中的所有方法,在編寫 Servlet 的時候,你只需要重寫你需要的方法就好了,并且該類還在原有 Servlet 接口上添加了一些與 HTTP 協(xié)議處理相關的方法,比 Servlet 接口的功能更強大。

    • Servlet 處理請求的方法一共有三種:
      ① 實現(xiàn)?service()?方法。
      ② 重寫?doGet()?和?doPost()?方法,并在?doGet()?中添加一句this.doPost(req, resp);(因為無論是get或post請求提交的數(shù)據(jù),處理方式都基本相同,下同)
      ③ 重寫?doGet()?和?doPost()?方法,并在?doPost()?中添加一句this.doGet()(req, resp);
    • 推薦方式①。

    Servlet 是單例的

    為什么Servlet是單例的

    瀏覽器多次對Servlet的請求,一般情況下,服務器只創(chuàng)建一個Servlet對象,也就是說,Servlet對象一旦創(chuàng)建了,就會駐留在內(nèi)存中,為后續(xù)的請求做服務,直到服務器關閉。

    每次訪問請求對象和響應對象都是新的

    對于每次訪問請求,Servlet引擎都會創(chuàng)建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,然后將這兩個對象作為參數(shù)傳遞給它調(diào)用的Servlet的service()方法,service方法再根據(jù)請求方式分別調(diào)用doXXX方法。

    線程安全問題

    當多個用戶訪問Servlet的時候,服務器會為每個用戶創(chuàng)建一個線程。當多個用戶并發(fā)訪問Servlet共享資源的時候就會出現(xiàn)線程安全問題。

    原則:
    1. 如果一個變量需要多個用戶共享,則應當在訪問該變量的時候,加同步機制synchronized (對象){}
    2. 如果一個變量不需要共享,直接在 doGet() 或者 doPost()定義.這樣不會存在線程安全問題

    > 這一部分參考文章:這里是鏈接

    HttpServletRequest 和 HttpServletResponse 對象

    對于每次訪問請求,Servlet引擎都會創(chuàng)建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,即 request 和 response 對象。

    既然 request 對象代表 http 請求,那么我們獲取瀏覽器提交過來的數(shù)據(jù),就找 request 對象?即可。response 對象代表 http 響應,那么我們向瀏覽器輸出數(shù)據(jù),找 response 對象即可。

    HttpServletRequest 常用方法

    • String getContextPath():
      獲取上下文路徑,<Context path="上下文" ../>
    • String getHeader(String headName):
      根據(jù)指定的請求頭獲取對應的請求頭的值.
    • String getRequestURI():
      返回當期請求的資源名稱. 上下文路徑/資源名
    • StringBuffer getRequestURL():
      返回瀏覽器地址欄的內(nèi)容
    • String getRemoteAddr():
      返回請求服務器的客戶端的IP

    獲取請求參數(shù)的方法:

    • String getParameter(String name):
      根據(jù)參數(shù)名稱,獲取對應參數(shù)的值.
    • String[] getParameterValues(String name):
      根據(jù)參數(shù)名稱,獲取該參數(shù)的多個值.
    • Enumeration?getParameterNames():
      獲取所有請求參數(shù)的名字
    • Map<String,String[]> getParameterMap():
      返回請求參數(shù)組成的Map集合.
      key:參數(shù)名稱
      value:參數(shù)值,封裝在String數(shù)組中.

    HttpServletResponse 常用方法

    • OutputStream getOutputStream():
      獲取字節(jié)輸出流:文件下載
    • Writer getWriter():
      獲取字符輸出流:輸出內(nèi)容
      設置文件輸出的編碼格式和內(nèi)容類型:resp.setContentType("text/html;charset=utf-8");

    GET 和 POST 的區(qū)別

    要知道,GET 和 POST 都是請求方式

    • GET:
      瀏覽器器地址欄:http://localhost/test.html?name=wmyskxz&sex=male
      這里提交了兩個參數(shù),一個是name屬性值為wmyskxz,另一個是sex屬性值為male,這是一種直接的請求方式,在請求資源后面跟上???符號與參數(shù)連接,其他的參數(shù)使用?&?符號連接。
    • 缺點:
      1.暴露請求信息,不安全
      2.請求信息不能超過1kb,可傳輸?shù)男畔⒂邢?#xff0c;不能上傳圖片

    • POST:
      瀏覽器地址欄:http://localhost/test.html#
    • 優(yōu)點:
      1.隱藏了請求信息,較安全(但仍可以通過相關工具訪問到數(shù)據(jù))
      2.POST 方式沒有限制請求的數(shù)據(jù)大小,可以做圖片的上傳

    但并不是所有的數(shù)據(jù)都需要使用 POST 請求來完成,事實上,GET 請求方式會比 POST 請求更快,當數(shù)據(jù)小并且安全性要求不是那么高的時候,GET 仍然是很好的選擇.(并且 GET 相較 POST 簡單)


    請求中文亂碼的處理

    在?Tomcat 服務器中,接受請求的時候,默認的編碼方式為 ISO-8859-1,而該編碼方式只占一個字節(jié),不支持中文(兩個字節(jié)),所以當我們做請求的時候,會出現(xiàn)亂碼的問題

    • 解決方案:
      1.對亂碼使用?ISO-8859-1?解碼,轉(zhuǎn)換成byte數(shù)組,恢復為二進制
      byte[] data = name.getBytes("ISO-8859-1");
      2.對byte數(shù)組重新進行 UTF-8 編碼:
      name = new String(data,"UTF-8");
      但是這樣會出現(xiàn)一個問題,那就是當表單數(shù)據(jù)太多的時候,這樣反復解碼-編碼,會很繁瑣。
    • 終極解決方案:
      1.對于 POST 請求:
      設置請求的編碼方式:request.setCharacterEncoding("UTF-8");
      注意:必須在獲取第一個參數(shù)之前設置,并且該方式只對 POST 方式有效。
      2.對于 GET 請求:
      重新設置 Tomcat 的編碼方式,修改 Tomcat 的配置文件:
      Tomcat根目錄/conf/server.xml(修改端口的那一行)

    Servlet 細節(jié)

    • 1.一個 Servlet 可以有多個?<url-pattern>?,可以使用多個資源名稱找到當前的 Servlet
    • 2.配置 Servlet 可以使用通配符(*)
      *表示任意字符
      /*:可以使用任意的字符訪問當前的 Servlet
      *.xxx:如 wmyskxz.wudi
    • 3.自定義的 Servlet 的?<servlet-name>?不能夠為 default ,使用它會造成項目下面的靜態(tài)資源找不到,在?Tomcat/conf/web.xml?文件中配置一個名字為default的Servlet,該Servlet在負責訪問項目下的靜態(tài)資源
    • 4.關于?Servlet 的初始化操作,如果初始化操作非常的耗時,那么第一個請求的用戶的用戶體驗就非常差
      解決思路:將初始化操作向前移,在服務器啟動的時候執(zhí)行 Servlet 的初始化

      ---

    通過注解配置 Servlet

    這是 Servlet 3.0 提出的新特性,支持注解配置,這大大簡化了我們的工作。

    在之前的開發(fā)工作中,我們總是去?web.xml?文件中進行配置,至少會出現(xiàn)8行:

    而當一個項目中存在很多 Servlet?,那么配置文件就會變得非常臃腫,不便于后期的維護,在 Servlet 3.0 推出之后,我們可以使用注解來配置 Servlet,上面 8 行的配置可以簡化為下面的簡單的注解:

    或者也可以使用屬性?value?定義訪問的 URL,只有 URL 這個屬性是必要的,name?是可以缺省的值,而默認的?value?也可以省略不寫,所以可以簡寫成:

    @WebServlet("/foreServlet")

    Web 組件之間的跳轉(zhuǎn)方式

    1.請求轉(zhuǎn)發(fā)(forward)

    又叫做直接轉(zhuǎn)發(fā)方式,客戶端和瀏覽器只發(fā)出一次請求,Servlet、HTML、JSP或其它信息資源,由第二個信息資源響應該請求,在請求對象request中,保存的對象對于每個信息資源是共享的。

    比如:從 AServlet 請求轉(zhuǎn)發(fā)到 BServlet

    • 語法:
    request.getRequestDispatcher(path).forward(request, response);

    參數(shù):path,要跳轉(zhuǎn)到的資源路徑:上下文路徑 / 資源路徑

    • 特點:
      1.地址欄中的地址【不會】改變
      通常看作是服務端的跳轉(zhuǎn)
      2.只有一個請求
      3.資源是共享的,也就是說在兩個 Servlet 中可以共享請求的資源
      可以通過request.setAttribute(String var1,Object var2)設置要共享的數(shù)據(jù)資源,并通過request.getAttribute(String var1);來獲取傳遞的資源
      4.【可以】訪問 WEB-INF 中的資源
      WEB-INF?文件夾是 Java Web 應用的默認安全目錄,即客戶端無法直接訪問,只有服務端可以訪問的目錄。
      如果想在頁面中直接訪問其中的文件,必須通過web.xml文件對要訪問的文件進行相應映射才能訪問。
      注意:在實際的開發(fā)中,可以把不希望用戶直接訪問到(通過瀏覽器輸入地址欄)的網(wǎng)頁放在文件夾中通過此方式訪問。
      5.請求轉(zhuǎn)發(fā)【不能】跨域訪問
      所謂的同域,是指域名,協(xié)議,端口均相同

    2.URl 重定向(redirect)

    又叫做間接轉(zhuǎn)發(fā)方式(Redirect)實際是兩次HTTP請求,服務器端在響應第一次請求的時候,讓瀏覽器再向另外一個URL發(fā)出請求,從而達到轉(zhuǎn)發(fā)的目的。

    比如:從AServlet重定向到BServlet

    • 語法:
    response.sendRedirect(String location);

    參數(shù):location,轉(zhuǎn)發(fā)到的資源路徑

    • 特點:
      1.地址欄中的地址【會】發(fā)生改變
      通常看作是客戶端跳轉(zhuǎn)
      2.有兩個請求
      3.在兩個 Servlet 中不可以共享請求中的數(shù)據(jù)
      4.最終的響應由 BServlet 來決定,和 AServlet 沒有關系
      5.【不可以】訪問 WEB-INF 中的資源
      6.請求轉(zhuǎn)發(fā)【能】跨域訪問
      就像是在網(wǎng)頁中點開了新的鏈接一樣
    • 總結(jié):URL 重定向相當于是將重定向的資源路徑,重新復制到瀏覽器地址欄中按下回車一樣,重新發(fā)送一次新的請求。

    3.請求包含(include)


    MVC 模式

    MVC 是一種分層的設計模式 。

    • M 代表 模型(Model)
      模型是什么呢? 模型就是數(shù)據(jù),就是dao,bean
    • V 代表 視圖(View)
      視圖是什么呢? 就是網(wǎng)頁, JSP,用來展示模型中的數(shù)據(jù)
    • C 代表 控制器(controller)
      控制器是什么??控制器的作用就是把不同的數(shù)據(jù)(Model),顯示在不同的視圖(View)上。

    這部分可以參考一下這里

    歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處!
    簡書ID:@我沒有三顆心臟
    github:wmyskxz

    總結(jié)

    以上是生活随笔為你收集整理的初学Java Web(4)——Servlet学习总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。