[toc]
## Servlet 簡介
Java Servlet是和平臺無關的服務器端組件,**它運行在Servlet容器中。Servlet容器負責Servlet和客戶的通信以及調用Servlet的方法,Servlet和客戶的通信采用“請求/響應”的模式**。

Servlet本質上就是一個運行在Servlet容器中的java類,現在充當容器的就是Tomcat
### 第一個Servlet——HelloWorld
1.創建一個Java類實現Servlet接口,用response給客戶端一個hello world的響應
~~~
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter pw = resp.getWriter();
//向客戶端發送信息
pw.println("hello world");
pw.close();
}
}
~~~
2.配置xml文件
~~~
<?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-name>first</servlet-name>
<servlet-class>Servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>first</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>
</web-app>
~~~
其中
~~~
<servlet>
<servlet-name>first</servlet-name>
<servlet-class>Servlet.FirstServlet</servlet-class>
</servlet>
~~~
servlet-name的值可以隨便起,但是Servlet-class必須嚴格按照類的位置寫
~~~
<servlet-mapping>
<servlet-name>first</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>
~~~
Servlet-mapping里的Servlet-name要和上面的保持一致,url-pattern表示的是為first映射一個訪問路徑/first(類似于提供一個能夠訪問到游戲角色的方式,其中/代表我們web應用的根目錄)
### Servlet的生命周期
1.創建Servlet對象(注意:只創建一個對象并且只初始化一次)
2.Servlet完成初始化
3.對外提供服務
4.在關閉服務器或者服務器重啟時銷毀
### load-on-startup
可以指定Servlet被創建的時機
~~~
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
~~~
在加載完Servlet后直接就創建了Servlet實例,并進行了初始化,在此期間我們并沒有提出請求。
如果配置了多個Servlet, load-on-startup的值越小越先啟動(包括0,負數不會被啟動,還是需要發出請求才創建實例并初始化);
### Servlet可能面臨的問題
1.創建多少個對象的問題:只會創建一個對象和初始化一次
2.由于是創建了一個對象
由于一個資源(Servlet)會同時被多個客戶端訪問就會出現多個線程訪問同一個資源的情況,
這個時候就要考慮線程安全問題
**如何避免**:不要在Servlet使用全局變量來作為下一步操作的判斷依據。如果非得這么做,需要加鎖。