title: servlet學(xué)習(xí)筆記
date: 2019-11-07 21:01:05
tags:
servlet學(xué)習(xí)筆記
servlet介紹
- 概念: servlet, server+applet的縮寫盹舞,從字面上的意思去理解就是服務(wù)器和小程序,javaee api給的解釋是這樣子的
A servlet is a small Java program that runs within a Web server.
-
即镶殷,servlet是一個運行在web服務(wù)器上的java小程序。javaee8 api文檔
Interface Servlet ,servlet是一個接口备典,定義了java類被瀏覽器訪問到(tomcat識別)的規(guī)則县貌。
使用servlet時,我們需要先自定義Java類磕瓷,實現(xiàn)servlet接口硝桩,然后重寫它的所有抽象方法沿猜。
servlet_define .png
入門:
The servlet is constructed, then initialized with the init method.
Any calls from clients to the service method are handled.
The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.
-
步驟
創(chuàng)建一個JavaEE項目
定義一個Java類,并且實現(xiàn)servlet接口
public class ServletDemo1 implements Servlet
實現(xiàn)servlet接口中的所有抽象方法
public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override //提供服務(wù)的方法 public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("hello servlet"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { }
- 配置servlet
<servlet> <servlet-name>demo1</servlet-name> <ser``vlet-class>cn.tomcat.fuzhennan.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>demo1</servlet-name> <url-pattern>/demo1</url-pattern> </servlet-mapping>
servlet執(zhí)行原理
當(dāng)用戶在瀏覽器地址欄輸入某個url路徑后(我們這里用http://localhost:8080/demo1來講解)碗脊,首先會去解析web.xml文件
然后在web.xml文件中找到<url-pattern>這個標(biāo)簽啼肩,看這個標(biāo)簽中是否含有/demo1這個路徑
如果有的話找servlet名為demo1的<servlet>,找到<servlet-class>中的內(nèi)容望薄,tomcat將全類名對應(yīng)的字節(jié)碼文件加載進(jìn)內(nèi)存疟游,即執(zhí)行Class.forName()方法
創(chuàng)建對象 cls.newInstance();
-
調(diào)用方法servlet中的方法
servlet_run.png
servlet的五個抽象方法
- init(),servlet容器在實例化servlet后會執(zhí)行該方法痕支,初始化配置信息颁虐。這個方法只會執(zhí)行一次。
void init(ServletConfig config)
throws ServletException
Called by the servlet container to indicate to a servlet that the servlet is being placed into service.
The servlet container calls the init method exactly once after instantiating the servlet. The init method must complete successfully before the servlet can receive any requests.
The servlet container cannot place the servlet into service if the init method
Throws a ServletException
Does not return within a time period defined by the Web server
- ServletConfig()卧须,這個方法會返回一個ServletConfig對象另绩,包括初始化的和startup的參數(shù)儒陨。
ServletConfig getServletConfig()
Returns a ServletConfig object, which contains initialization and startup parameters for this servlet. The ServletConfig object returned is the one passed to the init method.
Implementations of this interface are responsible for storing the ServletConfig object so that this method can return it. The GenericServlet class, which implements this interface, already does this.
- service(),該方法的功能是servlet容器允許servlet響應(yīng)請求笋籽,提供服務(wù)蹦漠。注意,只有init()成功的執(zhí)行后該方法才會執(zhí)行车海。
Called by the servlet container to allow the servlet to respond to a request.
This method is only called after the servlet's init() method has completed successfully.
The status code of the response always should be set for a servlet that throws or sends an error.
Servlets typically run inside multithreaded servlet containers that can handle multiple requests concurrently. Developers must be aware to synchronize access to any shared resources such as files, network connections, and as well as the servlet's class and instance variables. More information on multithreaded programming in Java is available in the Java tutorial on multi-threaded programming.
- getServletInfo()笛园,這個方法會返回servlet的一些信息,包括作者侍芝,版本研铆,版權(quán)等。
Returns information about the servlet, such as author, version, and copyright.
The string that this method returns should be plain text and not markup of any kind (such as HTML, XML, etc.).
- destroy()州叠,當(dāng)servlet中的service()方法退出時棵红,該方法就會執(zhí)行,且只執(zhí)行一次咧栗。當(dāng)執(zhí)行了該方法后逆甜,這個servlet實現(xiàn)的類便不會再執(zhí)行service()方法。該方法可以釋放任何資源致板。
Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. This method is only called once all threads within the servlet's service method have exited or after a timeout period has passed. After the servlet container calls this method, it will not call the service method again on this servlet.
This method gives the servlet an opportunity to clean up any resources that are being held (for example, memory, file handles, threads) and make sure that any persistent state is synchronized with the servlet's current state in memory.
servlet的生命周期
被創(chuàng)建
- 執(zhí)行init()方法交煞,只執(zhí)行一次
- servlet的創(chuàng)建
默認(rèn)情況下,當(dāng)?shù)谝淮伪辉L問時可岂,servlet會被創(chuàng)建
可以通過配置去指定servlet的創(chuàng)建時機
- servlet的創(chuàng)建
指定servlet的創(chuàng)建時機
1.默認(rèn)情況下错敢,第一次被訪問時創(chuàng)建
即<load-on-startup>值為負(fù)整數(shù),默認(rèn)值為-1
2.在tomcat服務(wù)器啟動時就創(chuàng)建
即<load-on-startup>值為>=0的整數(shù)缕粹,從0開始的整數(shù)中,越往后優(yōu)先級越低纸淮,0的優(yōu)先級最高
-
servlet中的init()方法只執(zhí)行一次平斩,說明一個servlet在內(nèi)存中只存在一個對象,即單例模式咽块。
當(dāng)用戶同時訪問共享資源時绘面,對資源進(jìn)行增刪改查 ,可能會存在線程安全問題侈沪。
解決方法:盡量不要在servlet中定義成員變量揭璃。非要定義的話不要賦值,修改亭罪。
提供服務(wù)
- 執(zhí)行service()方法瘦馍,可執(zhí)行多次
被銷毀
- 執(zhí)行destroy()方法,只執(zhí)行一次
- 服務(wù)器正常關(guān)閉時 应役,執(zhí)行該方法情组,釋放資源燥筷,servlet被銷毀。
servlet3.0后的注解配置
servlet3.0之后院崇,用戶不需要手動配置web.xml文件肆氓,可以通過注解的方式去配置。
-
實現(xiàn)步驟
首先創(chuàng)建一個Javaee項目底瓣,選擇servlet版本為3.0及以上谢揪,不需要勾選web.xml
第二步,在src目錄下創(chuàng)建一個Java類實現(xiàn)servlet接口
然后重寫servlet的所有抽象方法
在類上通過@WebServlet()實現(xiàn)注解配置
@WebServlet()源碼
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
通過WebServlet接口我們可以看出捐凭,他底層自動幫我們初始化了這些參數(shù)键耕,我們只需要添加自己的內(nèi)容即可。
我們在urlPatterns()中添加自己的路徑柑营,即可實現(xiàn)注解配置屈雄。如下:
@WebServlet(urlPatterns="/demo1")
- 我們還可以對其進(jìn)行簡化。一般來說官套,WebServlet中的這些參數(shù)酒奶,value()最為重要,我們就可以把url寫進(jìn)value中奶赔,如果只有一個屬性的話惋嚎,value還可以不寫,所以最終可以簡寫成如下:
@WebServlet("/demo1")
servlet體系結(jié)構(gòu)
- 通過看api文檔站刑,我們可以發(fā)現(xiàn)另伍,還實現(xiàn)了三個類實現(xiàn)了servlet接口。
- FacesServlet, GenericServlet, HttpServlet
- 這里我們主要講解后兩個绞旅,通過看api文檔摆尝,我們可以發(fā)現(xiàn),HttpServlet是繼承了GenericServlet因悲,所以他們的關(guān)系如下:
servlet | GenericServlet | HttpServlet
- 前面說到堕汞,我們每次新創(chuàng)建一個java類去實現(xiàn)servlet接口的時候,都必須要實現(xiàn)servlet接口的所有抽象方法晃琳,而實際上我們很可能只需要在service()方法里寫代碼讯检,其它方法是用不到的,所以我們可以用到GenericServlet卫旱。
- 步驟
新建一個Java類繼承GenericServlet
重寫service方法就好了
- 源碼分析
- 那么為什么繼承GenericServlet類就可以只需要重寫service方法呢人灼?通過源碼我們可以看到,他已經(jīng)自動幫我們寫了其它方法顾翼,進(jìn)行了空實現(xiàn)投放,在有需要的時候我們重寫就行,只把service方法進(jìn)行了抽象暴构,然后只需要復(fù)寫service方法就行跪呈。 部分源碼如下:
- 步驟
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final long serialVersionUID = 1L;
private transient ServletConfig config;
public GenericServlet() {
}
public void destroy() {
}
public ServletConfig getServletConfig() {
return this.config;
}
public String getServletInfo() {
return "";
}
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
}
- HttpServlet
- 原理
HttpServlet是對http協(xié)議進(jìn)行了封裝段磨,然后重寫了service方法。
- 步驟
1. 新建一個Java類繼承HttpServlet
2. 重寫doGet()/doPost()方法耗绿。(注意苹支,在瀏覽器地址欄輸入url是get請求,post請求得用表單的方式進(jìn)行)