# Servlet
## Servlet 簡介
Java Servlet是和平臺無關的服務器端組件,**它運行在Servlet容器中。Servlet容器負責Servlet和客戶的通信以及調用Servlet的方法,Servlet和客戶的通信采用“請求/響應”的模式**。
Servlet可完成如下功能:
創建并返回基于客戶請求的動態HTML頁面。
創建可嵌入到現有HTML 頁面中的部分HTML 頁面(HTML 片段)。
與其它服務器資源(如數據庫或基于Java的應用程序)進行通信。

Servlet本質上就是一個運行在Servlet容器中的Java類,現在充當Servlet容器的就是我們剛剛安裝的Tomcat
***
### 第一個Servlet——HelloWorld
1.創建一個Java類實現Servlet接口,并實現其中所有的方法;
~~~
package com.neusoft.javaweb;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServlet implements Servlet{
// 構造器
public HelloServlet() {
System.out.println("構造器");
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("service");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig");
return null;
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo");
return null;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destroy");
}
}
~~~
2.在web.xml配置和映射Servlet;
~~~
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!-- 配置和映射Servlet -->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
~~~
其中
~~~
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
</servlet>
~~~
表示的是為com.neusoft.javaweb.HelloServlet代表的類注冊一個名字為helloServlet(類似于為游戲角色創建一個角色名),helloServlet是可以自己隨意定制的
~~~
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
~~~
表示的是為helloServlet映射一個訪問路徑/hello(類似于提供一個能夠訪問到游戲角色的方式,其中/代表我們web應用的根目錄,即[http://localhost:8080/ykbbs/](http://localhost:8080/ykbbs/),也就是WebContent目錄)。
3.運行Tomcat,在瀏覽器中輸入[http://localhost:8080/ykbbs/hello](http://localhost:8080/ykbbs/hello),可以發現控制臺輸出了一些內容,首先是構造器,然后是init,再然后是service,然后每次刷新,每次都只出現了service,然后關閉服務,發現出現destory。
***
### Servlet的生命周期
①服務器加載Servlet
②創建Servlet實例
--只有第一次請求Servlet時,創建Servlet實例,調用構造器
③初始化init()
--只被調用一次,在創建好實例后立即被調用,用于初始化當前Servlet
④service()處理用戶請求
--可以被多次調用,每次請求都會調用service方法,實際用于響應請求的
⑤destory()銷毀
--只被調用一次,在當前Servlet所在的WEB應用被卸載前調用,用于釋放當前Servlet所占用的資源
***
### 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,負數不會被啟動,還是需要發出請求才創建實例并初始化);
***
## 注意:服務器不要空跑,保證有WEB應用在運行,否則不會有任何效果。
### Servlet映射細節
在Servlet映射到的URL中也可以使用 * 通配符,但是只能有兩種固定的格式:
一種格式是“* .擴展名”
~~~
<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
~~~
另一種格式是以正斜杠(/)開頭并以“/ * ”結尾。
~~~
<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>/action/*</url-pattern>
</servlet-mapping>
~~~
#### **注意:既帶 / 又帶 * 的,又帶擴展名的,是不合法的(例如:/*.do)。**
***
### ServletConfig
封裝了Servlet配置信息,并可以獲取ServletContext對象
它有4個方法:
**getInitParameterNames**獲取初始化參數的名字(集合)
**getInitParameter**(獲取初始化參數)
**getServletName**
**getServletContext**
①配置Servlet的初始化參數
~~~
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.neusoft.javaweb.HelloServlet</servlet-class>
<init-param>
<!-- 參數名 -->
<param-name>user</param-name>
<!-- 參數值 -->
<param-value>root</param-value>
</init-param>
<init-param>
<!-- 參數名 -->
<param-name>password</param-name>
<!-- 參數值 -->
<param-value>1230</param-value>
</init-param>
<load-on-startup>-1</load-on-startup>
</servlet>
~~~
配置在Servlet當中,且必須在load-on-startup之前
②獲取Servlet的初始化參數
~~~
public void init(ServletConfig servletConfig) throws ServletException {
String user = servletConfig.getInitParameter("user");
System.out.println("user:"+user);
Enumeration<String> names = servletConfig.getInitParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
String value = servletConfig.getInitParameter(name);
System.out.println("^^"+name+":"+value);
}
System.out.println("init");
}
~~~
③獲取Servlet的配置名稱(了解即可,使用較少)
~~~
String servletName = servletConfig.getServletName();
System.out.println(servletName);
~~~
④**getServletContext**獲取Servlet上下文 **(重點)**
~~~
// 代表當前web應用,當前web應用的大管家,可以從中獲取當前web應用各個方面的信息
ServletContext servletContext = servletConfig.getServletContext();
~~~
ServletContext常用的方法:
①獲取當前web應用的初始化參數
配置參數:
~~~
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
~~~
獲取參數:
~~~
// 與獲取Servlet初始化參數是一樣的
String driver = servletContext.getInitParameter("driver");
System.out.println("driver:"+driver);
~~~
#### 那么Servlet的初始化參數與當前web應用的初始化參數有什么區別?
一個是局部的,一個是全局的,全局的初始化參數,在任何的Servlet當中都可以獲取,而局部的只有當前Servlet可以獲取。
②獲取當前web應用某一個文件在服務器上的絕對路徑,而不是部署前的路徑(右鍵屬性中的路徑)
~~~
ServletContext servletContext = servletConfig.getServletContext();
String realPath = servletContext.getRealPath("index.jsp");
System.out.println(realPath);
~~~
③獲取當前WEB應用的名稱**getContextPath()**
~~~
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
~~~
這個名稱有時候是動態變換的,很常用的方法。
④獲取當前WEB應用的某一個文件對應的輸入流
getResourceAsStream(String path):path的 / 為當前web應用的根目錄
~~~
try {
ClassLoader classLoader = getClass().getClassLoader();
InputStream is1 = classLoader.getResourceAsStream("jdbc.properties");
System.out.println("1."+is1);
} catch (Exception e) {
e.printStackTrace();
}
try {
InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
System.out.println("2."+is2);
} catch (Exception e) {
e.printStackTrace();
}
~~~
⑤與attribute屬性相關的幾個方法(非常重要,后續講)
- 第一章 配置和安裝Tomcat
- 第二章 Servlet(一)
- 第三章 Servlet(二)
- 練習 一 . Servlet配置級獲取初始化參數
- 第四章 JSP(一)
- 第五章 JSP(二)
- 第六章 MVC設計模式
- 第七章 Cookie
- 第八章 Session
- 練習 二 . 簡易版購物車
- 第九章 EL表達式
- 第十章 JSTL
- 第十一章 過濾器
- 第十二章 監聽器
- 第十三章 文件的上傳與下載
- 復習總結
- 如何手動啟動Tomcat
- 如何修改Tomcat端口號
- 如何在web.xml中配置Servlet
- Servlet生命周期
- load-on-startup參數
- Servlet映射路徑
- POST和GET的區別
- JSP中9個隱式對象及功能
- 請求轉發及請求重定向的區別
- JSP指令有哪些
- 簡述對MVC設計模式的理解
- 簡述Cookie機制
- 簡述Session機制
- HttpSession的生命周期
- Cookie和Session有什么區別
- 簡述創建過濾器步驟
- 過濾器經典案例--統一編碼字符集
- getParameter與getAttribute的區別
- JSP頁面中可以包含哪些元素
- web應用中,是如何跟蹤用戶的
- InteliJ創建web項目