文章目錄
什麼是Servlet
Servlet就是運行在web服務器上的一個小的java程序,用於處理從web客戶端發送的請求,並對請求做出響應。
使用Servlet
- 編寫一個java類實現Servlet接口
- 配置Servlet(web.xml)
<!-- 配置Servlet -->
<servlet>
<!-- 配置Servlet -->
<servlet-name>LoginServlet</servlet-name>
<!-- 配置Servlet類的全路徑 -->
<servlet-class>com.itheima.controller.LoginServlet</servlet-class>
</servlet>
<!-- 配置Servlet的映射 -->
<servlet-mapping>
<!-- 配置Servlet -->
<servlet-name>LoginServlet</servlet-name>
<!-- 配置訪問路徑 -->
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
Servlet執行流程
Servlet的實現關係
- 基本的實現關係
Servlet接口——GenericServlet類(通用的Servlet,是一個與協議無關的Servlet)——HttpServlet類(Http專用的Servlet) - eclipse配置servlet
eclipse新建servlet——默認繼承HttpServlet類——去掉勾選構造方法——完成——自動配置web.xml
舊版本的servlet確實需要手動配置web.xml文件,但是servlet2.5以後,servlet的配置直接在Java代碼中進行註解配置(@WebServlet)。
Servlet的生命週期
servlet在第一次訪問的時候會被實例化,只要一被實例化那麼servlet中的init方法就會執行(init一個生命週期只執行一次)。任何一次從客戶端發送來的請求,servlet中的service方法就會執行(在service方法內部根據請求的方式不同調用不同的DOPOST、get方法)。當servlet從服務器中移除或者服務器關閉的時候servlet對象銷燬,裏面的destory方法就會執行,然後垃圾回收就會將其回收掉。
Servlet的啓動時加載
servlet默認在第一次訪問的時候創建對象,現在通過一個配置將servlet的實例化的過程放在服務器啓動的時候,讓服務器啓動時即創建Servlet對象。
在web.xml文件配置load-on-startup,數字寫1以上的整數。
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.itheima.controller.InitServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
Servlet中url-pattern的配置方式
//完全路徑匹配:以 / 開始,比如:/servlet、/aaa/servlet
//目錄匹配:以/開始,以/*結束,比如:/*、/aaa/*
//擴展名匹配:以*開始,比如:*.jsp、*.aaa
// *代表任意字符
//訪問的優先級:完全路徑匹配>目錄匹配>擴展名匹配
ServletContext對象
在服務器啓動時爲每個web項目創建一個單獨的ServletContext對象,一個web項目只有一個此對象。
-
獲取web項目信息
- 獲取文件的mime類型:
ServletContext servletContext = this.getServletContext(); String mimeType = servletContext.getMimeType("aa.txt");
- 獲取請求路徑的工程名
String path = servletContext.getContextPath();
- 獲取全局初始化參數(先在web.xml配置)
String username= servletContext.getInitParameter("username");
- 讀取web項目下的文件
Properties properties = new Properties();
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
properties.load(is);
//獲取數據
String url = properties.getProperty("url");
ServletContext作爲域對象存取數據
域對象:指的是將數據存入到域對象中,這個數據就會有一定的作用範圍。域指的是一定的作用範圍。
- 存入數據:setAttribute
- 獲取數據:getAttribute
- 移除數據:removeAttribute
ServletContext域對象作用範圍:整個web項目。
Response對象的API
-
response關於響應行的方法
- setStatus()
-
response關於響應頭的方法
- set開頭的方法:針對一個key一個value的情況
- add開頭的方法:針對一個key多個value的情況
-
response關於響應體的方法
- getWriter() 字符流
- getOutputStream() 字節流
-
response其他的API
- sendRedirect() 重定向
- setContentType 設置瀏覽器打開頁面時採用的字符集
- setCharacterEncoding() 設置響應字符流的的緩衝區字符集
- addCookie() 服務器向瀏覽器回寫cookie
Response對象的中文響應亂碼處理
//使用字節流的方式輸出中文
ServletOutputStream outputStream = response.getOutputStream();
//設置瀏覽器默認打開時候採用的字符集
response.setHeader("Content-Type","text/html;charset=UTF-8");
//設置中文轉成字節數組字符集編碼
outputStream.write("中文".getBytes("UTF-8"));
//設置瀏覽器默認打開時候採用的字符集
response.setHeader("Content-Type","text/html;charset=UTF-8");
//設置response獲得字符流的緩衝區的編碼
response.setCharacterEncoding("UTF-8");
//使用字符流輸出中文
response.getWriter().print("中文");
//簡化代碼
response.setContentType("text/html;charset=UTF-8");
Request對象
瀏覽器向服務器提交數據的封裝對象。
- request獲得客戶機的信息
//獲得請求方式
System.out.println("請求方式:"+request.getMethod());
//獲得客戶機的IP地址
System.out.println("客戶機IP地址:"+request.getRemoteAddr());
//獲得請求參數的字符串
System.out.println("請求參數的字符串:"+request.getQueryString());
//獲得請求路徑的URL和URI
System.out.println("請求路徑的URL:"+request.getRequestURL());
System.out.println("請求路徑的URI:"+request.getRequestURI());
- request獲得請求頭的信息
//獲得請求頭的信息
System.out.println("獲得客戶機瀏覽器類型:"+request.getHeader("User-Agent"));
- request對象接收表單參數
//單值獲取
String username = request.getParameter("username");
//獲取多值 例如:有多個愛好
String[] hobby = request.getParameterValues("hobby");
System.out.println(Arrays.toString(hobby));
//接收整個表單數據
Map<String, String[]> map = request.getParameterMap();
for(String key: map.keySet()) {
String[] value = map.get(key);
System.out.println(key+" "+Arrays.toString(value));
}
-
request對象中文亂碼處理
- post方式產生亂碼的原因:數據在請求體中,放入request的緩衝區中,緩衝區默認編碼爲ISO-8859-1(不支持中文)。將request的緩衝區編碼修改即可。
//post方式設置緩衝區編碼 request.setCharacterEncoding("UTF-8");
- get方式產生亂碼的原因:get方式提交的數據在請求行的url後面,在地址欄上就已經進行了一次url的編碼了。解決辦法:先將存入到request緩衝區中的內容以ISO-8859-1的格式提取,再以UTF-8的編碼解碼。
//post方式設置緩衝區編碼 request.setCharacterEncoding("UTF-8"); //get方式處理亂碼 String name = request.getParameter("name"); String encode = URLEncoder.encode(name,"ISO-8859-1"); String decode = URLDecoder.decode(encode,"UTF-8"); //簡化寫法,利用string的構造方法 String value = new String(name.getBytes("ISO-8859-1"),"UTF-8");