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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Servlet方法详解

發布時間:2025/3/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Servlet方法详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Servlet:

Servlet是SUN公司提供的一套規范,名稱就叫Servlet規范,它也是JavaEE規范之一。使用JavaEE的API。目前在Oracle官網中的最新版本是JavaEE8,

  • Servlet是一個運行在web服務端的java小程序
  • 它可以用于接收和響應客戶端的請求
  • 要想實現Servlet功能,可以實現Servlet接口,繼承GenericServlet或者HttpServlet
  • 每次請求都會執行service方法
  • Servlet還支持配置
Servlet執行過程:
  • 客戶端瀏覽器發起請求
  • Tomcat服務器解析URL
  • 通過URL找到對應的應用
  • 通過應用找到web.xml
  • 解析請求資源地址URL
  • 找到應用的資源
  • 執行service方法,響應給客戶端瀏覽器
  • Servlet關系視圖:

    Servlet實現方式:

    1、 實現Servlet接口,接口中的方法必須全部實現。

    表示接口中的所有方法在需求方面都有重寫的必要。這種方式支持最大程度的自定義。

    2、繼承GenericServlet,service方法必須重寫,其他方可根據需求,選擇性重寫。

    表示只在接收和響應客戶端請求這方面有重寫的需求,而其他方法可根據實際需求選擇性重寫,使開發Servlet變得簡單。但是,此種方式是和HTTP協議無關的。

    3、繼承HttpServlet,它是javax.servlet.http包下的一個抽象類,是GenericServlet的子類。如果選擇繼承HttpServlet時,只需要重寫doGet和doPost方法,不要覆蓋service方法。

    表示我們的請求和響應需要和HTTP協議相關。也就是說通過HTTP協議來訪問的。那么每次請求和響應都符合HTTP協議的規范。請求的方式就是HTTP協議所支持的方式

    實現Servlet:
    public class ServletDemo03 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("實現Servlet方式");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {} }
    繼承GenericServlet:
    public class ServletDemo01 extends GenericServlet {@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("service方法執行了...");} }
    繼承HttpServlet::
    public class ServletDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Servlet執行了");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }
    配置文件:
    <?xml version="1.0" encoding="UTF-8"?> <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_4_0.xsd"version="4.0"><!--Servlet配置--><servlet><servlet-name>servletDemo</servlet-name><servlet-class>com.example.demo.ServletDemo</servlet-class></servlet><!--映射配置--><servlet-mapping><servlet-name>servletDemo</servlet-name><url-pattern>/servletDemo</url-pattern></servlet-mapping><!--生命周期配置--><servlet><servlet-name>servletDemo02</servlet-name><servlet-class>com.example.demo.ServletDemo02</servlet-class></servlet><servlet-mapping><servlet-name>servletDemo02</servlet-name><url-pattern>/servletDemo02</url-pattern></servlet-mapping></web-app>
    Servlet生命周期:
    • 對象的生命周期,就是對象從生到死的過程,
    • 出生:請求第一次到達Servlet時,對象就創建出來,并且初始化成功。只出生一次,就放到內存中。
    • 活著:服務器提供服務的整個過程中,該對象一直存在,每次都是執行service方法。
    • 死亡:當服務停止時,或者服務器宕機時,對象消亡。
    • Servlet對象只會創建一次,銷毀一次。所以,Servlet對象只有一個實例。如果一個對象實例在應用中是唯一的存在,用了單例模式。

    演示:

    public class ServletDemo02 extends HttpServlet {// 對象出生@Overridepublic void init() throws ServletException {System.out.println("出生了");}// 對象服務@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("收到客戶端請求");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}// 對象死亡@Overridepublic void destroy() {System.out.println("掛了");} }
    線程安全:

    在Servlet中定義了類成員之后,多個瀏覽器都會共享類成員的數據。其實每一個瀏覽器端發送請求,就代表是一個線程,那么多個瀏覽器就是多個線程,多個線程會共享Servlet類成員中的數據,其中任何一個線程修改了數據,都會影響其他線程。因此,所以Servlet它不是線程安全的。分析產生這個問題的根本原因,其實就是因為Servlet是單例,單例對象的類成員只會隨類實例化時初始化一次,之后的操作都是改變,而不會重新初始化。

    解決:

    在Servlet中定義類成員要慎重。如果類成員是共用的,并且只會在初始化時賦值,其余時間都是獲取的話,那么是沒問題。如果類成員并非共用,或者每次使用都有可能對其賦值,那么就要考慮線程安全問題了,把它定義到doGet或者doPost方法里面去就可以了。或者是直接加synchronized

    演示:

    public class ServletDemo03 extends HttpServlet {private String username;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {synchronized (this) {// 在這里聲明的話,就是把成員變量變成局部變量,谷歌進來是一個username,火狐進來又是另一個就不會出現出數據不安全了// String username = null;// String getParameter(String name):根據參數名稱獲取參數值username = req.getParameter("username");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// resp.getWriter 傳數據給前端PrintWriter writer = resp.getWriter();writer.println("username:" + username);writer.close();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);} }
    Servlet映射三種方式:
  • 指名道姓,給具體的名稱,訪問路徑必須和配置的一樣
  • /開頭+通配符的方式,只要符合目錄結構,無視結尾
  • 通配符+固定格式結尾方式,只要符合固定結尾,無視前面路徑
  • 說明:映射優先級:越具體優先級越高,1>2>3

    演示:

    <?xml version="1.0" encoding="UTF-8"?> <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_4_0.xsd"version="4.0"><!--&lt;!&ndash;ServletHttp配置&ndash;&gt;<servlet><servlet-name>servletDemo</servlet-name><servlet-class>com.example.demo.ServletDemo</servlet-class></servlet><servlet-mapping><servlet-name>servletDemo</servlet-name><url-pattern>/servletDemo</url-pattern></servlet-mapping>--><!-- &lt;!&ndash;/開頭+通配符的方式&ndash;&gt;<servlet><servlet-name>servletDemo</servlet-name><servlet-class>com.example.demo.ServletDemo</servlet-class></servlet><servlet-mapping><servlet-name>servletDemo</servlet-name><url-pattern>/servlet/*</url-pattern></servlet-mapping>--><!--通配符+固定格式結尾 結尾寫什么就寫什么,開心就好--><servlet><servlet-name>servletDemo</servlet-name><servlet-class>com.example.demo.ServletDemo</servlet-class></servlet><servlet-mapping><servlet-name>servletDemo</servlet-name><url-pattern>*.itzhuzhu</url-pattern></servlet-mapping> </web-app>

    實現類:

    public class ServletDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 定義一個商品金額int money = 1000;// 獲取訪問路徑String uri = req.getRequestURI();// public int lastIndexOf(int ch): 返回指定字符在此字符串中最后一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。uri = uri.substring(uri.lastIndexOf("/"));// 條件判斷if ("/vip".equals(uri)) {System.out.println("原價:" + money + "尊敬的Vip您的折后價是:" + money * 0.8);} else if ("/svip".equals(uri)) {System.out.println("原價:" + money + "尊敬的Sip您的折后價是:" + money * 0.1);} else {System.out.println("會員都不開還想打折?打骨折");}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }
    Servlet創建時機:

    第一種:服務器加載時創建

    優勢:
    在服務器啟動時,就把需要的對象都創建完成了,從而在使用的時候減少了創建對象的時間,提高了首次執行的效率。
    弊端:
    因為在應用加載時就創建了Servlet對象,因此,導致內存中充斥著大量用不上的Servlet對象,造成了內存的浪費。

    第二種:第一次訪問時創建

    優勢:
    就是減少了對服務器內存的浪費,因為那些一直沒有被訪問過的Servlet對象都沒有創建,因此也提高了服務器的啟動時間。
    弊端:
    如果有一些要在應用加載時就做的初始化操作,它都沒法完成,從而要考慮其他技術實現。
    修改創建時機:在標簽中添加標簽

    標簽里的數字越小優先級越高,正整數代表服務器加載時創建,負數或不寫代表第一次訪問的時候創建

    <servlet><servlet-name>servletDemo</servlet-name><servlet-class>com.example.demo.ServletDemo</servlet-class><!--數字越小越高,負數或者不寫就是第一次訪問的時候創建--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>servletDemo</servlet-name><url-pattern>/servletDemo</url-pattern></servlet-mapping>
    默認Servlet:

    默認Servlet是由服務器提供的一個Servlet,它配置在Tomcat的conf目錄下web.xml中。它的映射路徑是<url-pattern>/<url-pattern>,在發送請求時,首先會在應用中的web.xml中查找映射配置,找到就執行。找不到對應的Servlet路徑時,就去找默認的Servlet,由默認Servlet處理。

    ServletConfig:

    ServletConfig是Servlet的配置參數對象,在Servlet規范中,允許為每個Servlet都提供一些初始化配置。所以,每個Servlet都一個自己的ServletConfig。它的作用是在Servlet初始化期間,把一些配置信息傳遞給Servlet。比如servlet是個孩子,ServletConfig就是保姆

    生命周期:

    由于它是在初始化階段讀取了web.xml中為Servlet準備的初始化配置,并把配置信息傳遞給Servlet,所以生命周期與Servlet相同。需要注意的是,如果Servlet配置了1,那么ServletConfig也會在應用加載時創建。

    配置ServletConfig:

    在<servlet>標簽中,通過<init-param>標簽配置,有兩個子標簽
    <param-name>:代表初始化參數的key
    <param-value>:代表初始化參數的value

    ServletConfig方法:
    返回值方法名說明
    StringgetInitParameter(String name)根據參數名稱獲取參數的值
    EnumerationgetInitParameterNames()獲取所有參數名稱的枚舉
    StringgetServletName獲取Servlet的名稱
    SerlvetContextgetServletContext獲取ServletContext對象
    演示:

    配置信息:

    <servlet><servlet-name>servletDemo05</servlet-name><servlet-class>com.example.demo.ServletDemo05</servlet-class><!--配置ServletConfig,是以鍵值對的形式存在的--><init-param><param-name>itz</param-name><param-value>itzhuzhu</param-value></init-param></servlet><servlet-mapping><servlet-name>servletDemo05</servlet-name><url-pattern>/servletDemo05</url-pattern></servlet-mapping>

    實現類:

    public class servletDemo04 extends HttpServlet {// 聲明ServletConfigprivate ServletConfig config;// 因為ServletConfig是在初始化期間傳遞信息,所以要在init方法里去獲取@Overridepublic void init(ServletConfig config) throws ServletException {// 通過init方法,對ServletConfig對象賦值this.config = config;}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// getInitParameter(String name):根據key獲取valueString encodingValue = config.getInitParameter("encoding");System.out.println(encodingValue);// getInitParameterNames():獲取所有keyEnumeration<String> keys = config.getInitParameterNames();while (keys.hasMoreElements()) {// 獲取每一個keyString key = keys.nextElement();// 根據key獲取valueString value = config.getInitParameter(key);System.out.println(key + " : " + value);}// getServletName 獲取Servlet的名稱String servletName = config.getServletName();System.out.println(servletName);// getServletContext 獲取ServletContext對象ServletContext servletContext = config.getServletContext();System.out.println(servletContext);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }

    ServletContext:

    ServletContext對象,它是應用上下文對象。每一個應用有且只有一個ServletContext對象。

    作用:

    它可以配置和獲取應用的全局初始化參數,實現所有Servlet之間的數據共享。

    生命周期:
    • 出生: 應用一加載,該對象就被創建出來了。一個應用只有一個實例對象。(Servlet和ServletContext都-是單例的)
    • 活著:只要應用一直提供服務,對象就一直存在。
    • 死亡:應用被卸載(或者服務器掛了),對象死亡。
    域對象概念:
    • 域對象:指的是對象有作用域(作用范圍)
    • 域對象的作用:域對象可以實現數據共享。
    • 不同作用范圍的域對象,共享數據的能力不一樣。在Servlet規范中,一共有4個域對象。ServletContext就是其中一個。也是web應用中最大的作用域,叫application域。每個應用只有一個application域(應用域),它可以實現整個應用間的數據共享功能。
    ServletContext配置:

    ServletContext被稱之為應用上下文對象,所以它的配置是針對整個應用的配置,而非某個特定Servlet的配置。它的配置被稱為應用的初始化參數配置。

    配置的方式,需要在標簽中使用來配置初始化參數

    <param-name>:全局初始化參數的key
    <param-value>:全局初始化參數的value

    常用方法:
    返回值方法名說明
    StringgetInitParameter(String name)根據名稱獲取全局配置的參數
    StringgetContextPath()獲取當前應用訪問的虛擬目錄
    StringgetRealPath根據虛擬目錄獲取應用部署的磁盤絕對路徑
    應用域常用方法:
    返回值方法名說明
    voidsetAttribute(String name,Object value)向應用域對象中存儲數據
    ObjectgetAttribute(String name)通過名稱獲取應用域對象中的數組
    voidremoveAttribute(String name)通過名稱移除應用域對象中的數據

    配置文件:

    <!--因為servletContext它不屬于某一個servlet,它是配置全局的,所以不能寫在servlet里--><context-param><param-name>desc</param-name><param-value>This is Ser vletContextDemo</param-value></context-param><servlet><servlet-name>servletContextDemo</servlet-name><servlet-class>com.example.demo.ServletContextDemo</servlet-class></servlet><servlet-mapping><servlet-name>servletContextDemo</servlet-name><url-pattern>/servletContextDemo</url-pattern></servlet-mapping>

    實現類:

    public class ServletContextDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 獲取ServletContext對象 , GenericServlet底層已經實現了getInitParameter所以可以直接調用 ServletConfig sc = this.getServletConfig();ServletContext context = getServletContext();//獲取全局配置參數的descString value = context.getInitParameter("desc");System.out.println(value);//獲取應用的訪問虛擬目錄String contextPath = context.getContextPath();System.out.println(contextPath);//根據虛擬目錄獲取應用部署的磁盤絕對路徑String realPath = context.getRealPath("/");System.out.println(realPath);// 在src、wabapp、webinf創建三個文件獲取路徑//獲取a.txt文件的絕對路徑String a = context.getRealPath("/WEB-INF/classes/a.txt");System.out.println(a);//獲取b.txt文件的絕對路徑String b = context.getRealPath("/b.txt");System.out.println(b);String c = context.getRealPath("/WEB-INF/c.txt");System.out.println(c);//向域對象中存儲數據context.setAttribute("username", "itzhuzhu");//移除域對象中username的數據,刪除了再訪問就變成null了context.removeAttribute("username");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }

    獲取共享數據:

    public class ServletDemo05 extends HttpServlet {// 聲明ServletConfigprivate ServletConfig config;// 因為ServletConfig是在初始化期間傳遞信息,所以要在init方法里去獲取@Overridepublic void init(ServletConfig config) throws ServletException {// 通過init方法,對ServletConfig對象賦值this.config = config;}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// getServletContext 獲取ServletContext對象ServletContext servletContext = config.getServletContext();System.out.println(servletContext);// getAttribute(String name) 通過名稱獲取應用域對象中的數組Object username = servletContext.getAttribute("username");System.out.println(username);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }

    Request方法詳解:

    總結

    以上是生活随笔為你收集整理的Servlet方法详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。