需要掌握的知識點:1、Servlet程序編寫 ----- 生命周期2、ServletAPI Request Response 3、Cookie 和 session
Servlet 用來 動態(tài)web資源 開發(fā)靜態(tài)web資源 : 固定數(shù)據(jù)文件動態(tài)web資源 : 通過程序動態(tài)生成數(shù)據(jù)文件
Servlet技術(shù)基于Request-Response編程模型 ---- HTTP協(xié)議也是基于請求響應(yīng) 模型 * Servlet技術(shù) 用來 開發(fā)基于HTTP web 應(yīng)用程序
接觸 JavaEE API ------ 程序 接口 和 已經(jīng)實現(xiàn)接口 類的 使用 JavaEE ---- Java Platform, EnterPRise Edition 縮寫
Servlet快速入門1、創(chuàng)建web project 2、編寫 class 繼承 HttpServlet 3、在web.xml 配置 Servlet程序 虛擬訪問路徑 * 用戶在瀏覽器上通過這個路徑 訪問編寫Servlet程序 4、覆蓋doGet或者doPost方法 進(jìn)行輸出
* Servlet 動態(tài)生成 網(wǎng)頁文件
執(zhí)行過程1、用戶在客戶端發(fā)起url請求 : http://localhost/day05/hello ----- web.xml /hello 映射 HelloServlet程序2、用戶提交請求時,get方式提交 執(zhí)行 HelloServlet的 doGet方法 post方式提交 執(zhí)行 HelloServlet的doPost 方法
Servlet程序在編寫和運(yùn)行時,需要javaee 類庫 (API支持)* 在學(xué)習(xí)javase List 需要 import java.util.List 需要 jre/lib/rt.jar * MyEclipse 自動導(dǎo)入 javaee5 liberary 存在 javaee.jar 提供 Servlet 需要類 API支持 (開發(fā)環(huán)境使Servlet程序正常編譯)* Serlvet程序運(yùn)行tomcat環(huán)境中 沒有javaee.jar , 在 tomcat/lib/servlet-api.jar 提供Servlet程序運(yùn)行需要 類API 支持 (運(yùn)行環(huán)境需要的)
手動編寫Servlet運(yùn)行1、在webapps 新建 day05test目錄 --- 虛擬應(yīng)用2、在day05test 新建 WEB-INF/classes3、將編寫Servlet的java源碼文件 放入 classes ,在 WEB-INF 配置web.xml 4、編譯Servlet的 java程序 javac -classpath E:/apache-tomcat-6.0.14/lib/servlet-api.jar HelloServlet.java // 通過 -classpath 指定 Servlet需要jar 包生成Servlet package結(jié)構(gòu) javac -d . -classpath E:/apache-tomcat-6.0.14/lib/servlet-api.jar HelloServlet.java
Servlet運(yùn)行原理分析編寫Servlet程序沒有 main函數(shù) ---- tomcat調(diào)用Servlet程序執(zhí)行
通過myeclipse向?qū)?創(chuàng)建Servlet ---- 創(chuàng)建Servlet程序,生成web.xml 配置 * 生成Servlet信息非常復(fù)雜,想生成Servlet 內(nèi)容整潔一些,精簡一些 ------ 修改Servlet模板 1、myeclipse工具 ---- 安裝目錄 common / pluginscom.genuitec.eclipse.wizards_8.5.0.me201003052220.jar
2、解壓縮 templates/Servlet.java --- 這個就是Servlet模板
通過API Servlet繼承關(guān)系 Servlet接口 ---- 實現(xiàn)類 : GenericServlet ------ 子類 HttpServlet ------ 編寫Servlet 繼承HttpServlet * 編寫Servlet 間接 實現(xiàn) Servlet 接口 (簡化開發(fā))Servlet接口 提出,為了解決基于請求-響應(yīng)模型數(shù)據(jù)處理 (并沒有涉及與HTTP協(xié)議相關(guān) API)GenericServlet 實現(xiàn)接口 通用Servlet 也沒有提供與 HTTP協(xié)議相關(guān) API HttpServlet 引入與 協(xié)議相關(guān) API
Servlet生命周期 init(ServletConfig config) 初始化 service(ServletRequest req, ServletResponse res) 提供服務(wù)方法destroy() 銷毀
1、tomcat服務(wù)器啟動時,沒有創(chuàng)建Servlet對象2、第一次訪問時,tomcat構(gòu)造Servlet對象,調(diào)用 init,執(zhí)行service 3、從第二次以后訪問 tomcat 不會從新創(chuàng)建Servlet對象,也不會調(diào)用init ---- 每一次訪問都會調(diào)用service 4、當(dāng)服務(wù)器重啟或正常關(guān)閉時 調(diào)用destroy (正常關(guān)閉 shutdown.bat)
Servlet對象是tomcat創(chuàng)建的,每次請求調(diào)用Servlet中service方法,tomcat服務(wù)器會在每次調(diào)用Servlet的service方法時,為該方法創(chuàng)建Request對象和Response對象 * 在 JavaEE API 中沒有Request和Response實現(xiàn)類 ----- 實現(xiàn)類由Servlet服務(wù)器提供的,tomcat提供實現(xiàn)類 weblogic 提供實現(xiàn)類
service方法 和 HttpServlet doGet/doPost 關(guān)系區(qū)別? ----- 必須閱讀HttpServlet源代碼 在HttpServlet代碼實現(xiàn)中,根據(jù)請求方式不同 調(diào)用相應(yīng)doXXX方法 get方式請求 --- doGet post方式 --- doPost
配置Servlet隨tomcat服務(wù)器啟動時 進(jìn)行初始化 --- <load-on-startup >*<load-on-startup > 參數(shù)可以是一個數(shù)字 0-9 代表服務(wù)器加載優(yōu)先級 0 最高 例如:在tomcat啟動時,想通過Servlet加載一些框架配置文件 配置隨服務(wù)器啟動 (struts1 )
結(jié)論:1、編寫Servlet 繼承HttpServlet2、編寫Servlet 不需要覆蓋service方法,只需要覆蓋doGet和doPost 方法
Servlet初始化時覆蓋init() ,無需覆蓋init(config) ?? * init(Config) 調(diào)用 init()
當(dāng)doGet和doPost代碼邏輯相同時,可以相互調(diào)用,簡化編程
一個Servlet可以配置多個url-pattern URL 配置格式 三種:1、完全路徑匹配 (以/開始 ) 例如:/hello /init * 當(dāng)前工程沒有被正確發(fā)布,訪問該工程所有靜態(tài)資源、動態(tài)資源 發(fā)生404 ----- 工程啟動時出錯了 * 查看錯誤時 分析錯誤1) 單一錯誤 : 從上到下 查看第一行你自己寫代碼 (有的錯誤與代碼無關(guān),查看錯誤信息)2)復(fù)合錯誤 Caused by ---- 查看最后一個Caused by * Invalid <url-pattern> init2 in servlet mapping
2、目錄匹配 (以/開始) 例如:/* /abc/* / 代表網(wǎng)站根目錄
3、擴(kuò)展名 (不能以/開始) 例如:*.do *.action 典型錯誤 /*.do
優(yōu)先級:完全匹配>目錄匹配 > 擴(kuò)展名匹配
路徑問題:編寫九九乘法表1、需要用戶在客戶端輸入一個數(shù)字2、Servlet接收客戶輸入數(shù)字 打印對應(yīng)乘法表
在chengfabiao.html 通過 action 訪問 ChengfabiaoServlet 路徑可以用絕對路徑和相對路徑
相對路徑:相對當(dāng)前網(wǎng)頁地址 路徑 例如 chengfabiao ./chengfabiao ../chengfabiao例如: http://localhost/day05/chengfabiao.html 提交 action="chengfabiao"* 將url最后地址換成相對路徑 結(jié)果: http://localhost/day05/chengfabiao ----- 服務(wù)器端 /chengfabiao
例如: http://localhost/day05/aaa/chengfabiao.html 提交 action="chengfabiao"結(jié)果: http://localhost/day05/aaa/chengfabiao ----- 服務(wù)器 /chengfabiao * /aaa/chengfabiao 與服務(wù)器 /chengfabiao 不匹配 出現(xiàn)404
http://localhost/day05/aaa/chengfabiao.html 提供 action="../chengfabiao" 結(jié)果:http://localhost/day05/aaa/../chengfabiao ---- > ..和/aaa抵消 http://localhost/day05/chengfabiao 可以匹配服務(wù)器 /chengfabiao
結(jié)論:如果用相對路徑提交請求,考慮當(dāng)前路徑, 當(dāng)前訪問服務(wù)器資源路徑不同 ---- 相對路徑寫法不同
絕對路徑 解決相對路徑,會根據(jù)當(dāng)前地址改變問題。 例如: /day05/chengfabiao 、http://localhost/day05/chengfabiao絕對路徑 以/開始 /訪問服務(wù)器根目錄 例如: 客戶端訪問服務(wù)器,不管當(dāng)前路徑是什么 --- / 服務(wù)器根目錄 http://localhost/day05 --- 找到虛擬目錄day05工程 /day05/chengfabiao --- 找到 day05工程下配置 虛擬路徑/chengfabiao
結(jié)論: 客戶端路徑 /工程虛擬目錄/servlet虛擬路徑 例如:/day05/chengfabiao服務(wù)器端 配置web.xml 不需要寫工程虛擬目錄 只要直接寫/servlet虛擬路徑 例如:/chengfabiao
----------------------------------------------------------------------------掌握Servlet程序編寫通過路徑 訪問Servlet 程序* Servlet 生命周期
initservicedestroy
學(xué)習(xí)init方法 ---- init(ServletConfig) ---- 通過ServletConfig 獲得Servlet初始化參數(shù)1、創(chuàng)建一個Servlet2、在web.xml 中 <servlet> 標(biāo)簽內(nèi) 通過 <init-param> 標(biāo)簽 為Servlet配置初始化參數(shù) <init-param> <param-name>itcast</param-name> <param-value>傳智播客</param-value> </init-param>
3、在Servlet程序中通過ServletConfig對象 獲得itcast對應(yīng)數(shù)據(jù) getInitParameter ------ 通過name獲得valuegetInitParameterNames ----- 獲得所有name
* 思考 :如何在doGet 或 doPost 方法中 獲得 Servlet初始化參數(shù) 將ServletConfig對象保存實例成員變量 GenericServlet 已經(jīng)將ServletConfig 保存成員變量 ----- 在子類中通過 getServletConfig方法 獲得 初始化參數(shù)
結(jié)論:子類Servlet不需要覆蓋 init(ServletConfig) , 只需要通過GenericServlet中 getServletConfig() 獲得ServletConfig對象
應(yīng)用:在init-param 指定配置文件位置和名稱,配置Servlet隨服務(wù)器啟動創(chuàng)建 load-on-startup
* ServletConfig 配置初始化數(shù)據(jù),只能在配置Servlet獲得,其它Servlet無法獲得 ----- 每個Servlet程序都對應(yīng)一個ServletConfig對象
ServletContext 是Servlet上下文對象 每一個工程 對會創(chuàng)建 單獨(dú)ServletContext對象,這個對象代表當(dāng)前web工程 操作ServletContext 必須通過ServletConfig 獲得對象
應(yīng)用:1、 獲得整個web應(yīng)用初始化參數(shù)2、 實現(xiàn)全局?jǐn)?shù)據(jù)共享3、 實現(xiàn)服務(wù)器端轉(zhuǎn)發(fā)功能4、 讀取web工程資源文件
1、獲取WEB應(yīng)用的初始化參數(shù) 和 ServletConfig 對象不同 * ServletConfig對象配置參數(shù),只對配置Servlet有效,如果配置參數(shù),所有Servlet都可以訪問 通過ServletContext<context-param>



1 @Override 2 public void init(ServletConfig config) throws ServletException { 3 String name = config.getInitParameter("shellway"); 4 System.out.println(name); 5 //Enumeration相當(dāng)于Iterator 它是Iterator的前身 6 Enumeration<String> names = config.getInitParameterNames(); 7 while (names.hasMoreElements()) { 8 String name2 = (String) names.nextElement(); 9 System.out.println(name2+":"+config.getInitParameter(name2));10 }11 }ServletConfig對象配置參數(shù)的獲取
1 public void doGet(HttpServletRequest request, HttpServletResponse response)2 throws ServletException, IOException {3 System.out.println(getServletConfig().getInitParameter("shellway"));4 ServletContext sc = getServletContext();5 System.out.println(sc.getInitParameter("XXX"));6 }全局的配置參數(shù),所有Servlet都可以訪問,通過ServletContext獲取2、通過ServletContext 在多個Servlet間 共享數(shù)據(jù) 在ServletContext中 保存站點訪問次數(shù) ,每當(dāng)一個用戶訪問站點,將訪問次數(shù)+1 在CountServlet 初始化過程中,向ServletContext 保存訪問次數(shù) ---- 0 --------------> ServletContext setAttribute
每次訪問次數(shù) +1 --- 數(shù)據(jù)存放ServletContext中 ---- 所有Servlet都可以獲得該數(shù)據(jù)
* 在ServletContext中保存數(shù)據(jù),所有Servlet都可以訪問

1 package com.shellway.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletConfig; 6 import javax.servlet.ServletContext; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 public class HelloServlet2 extends HttpServlet {13 @Override14 public void init() throws ServletException {15 ServletContext sc = getServletContext();16 sc.setAttribute("times", 0);17 System.out.println("已經(jīng)初始化。。。");18 }19 20 public void doGet(HttpServletRequest request, HttpServletResponse response)21 throws ServletException, IOException {22 ServletContext sc = getServletContext();23 int time=(Integer)sc.getAttribute("times");24 time++;25 sc.setAttribute("times", time);26 System.out.println("被訪問第:"+time+"次");27 }28 29 public void doPost(HttpServletRequest request, HttpServletResponse response)30 throws ServletException, IOException {31 32 doGet(request, response);33 34 }35 }統(tǒng)計網(wǎng)頁訪問次數(shù):HelloServlet2
1 package com.shellway.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletContext; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 public class CountServlet extends HttpServlet {13 14 public void doGet(HttpServletRequest request, HttpServletResponse response)15 throws ServletException, IOException {16 ServletContext sc = getServletContext();17 int time=(Integer)sc.getAttribute("times");18 PrintWriter pw = response.getWriter();19 pw.write("this site has been visit "+time+" times");20 21 }22 23 public void doPost(HttpServletRequest request, HttpServletResponse response)24 throws ServletException, IOException {25 26 doGet(request, response);27 28 }29 }統(tǒng)計網(wǎng)頁訪問次數(shù):CountServlet3、通過ServletContext 完成服務(wù)器程序轉(zhuǎn)發(fā) 什么是轉(zhuǎn)發(fā)? 轉(zhuǎn)發(fā)和重定向區(qū)別 ?getRequestDispatcher(java.lang.String path) ---- 完成轉(zhuǎn)發(fā)
使用轉(zhuǎn)發(fā)還是重定向? ---- 轉(zhuǎn)發(fā)性能好于重定向,請求次數(shù)好
統(tǒng)計字母次數(shù)request.getParameter("content") 獲得form 提交內(nèi)容 content 就是 textarea name屬性

1 package com.shellway.servletcontext; 2 3 import java.io.IOException; 4 5 import javax.servlet.RequestDispatcher; 6 import javax.servlet.ServletContext; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 public class CountForA_Z extends HttpServlet {13 14 public void doGet(HttpServletRequest request, HttpServletResponse response)15 throws ServletException, IOException {16 //拿到請求數(shù)據(jù)17 String content = request.getParameter("content");18 //減少工作量,把內(nèi)容都轉(zhuǎn)為大寫19 String upcontent = content.toUpperCase();20 //為26個字母創(chuàng)建數(shù)組,每個字母對應(yīng)一個數(shù)組位置,每個數(shù)組位置存放統(tǒng)計該字母的數(shù)量21 int[] arr = new int[26];22 for (int i = 0; i < upcontent.length(); i++) {23 //charAt(int index)返回指定索引處的 char 值。索引范圍為從 0 到 length()-124 char c = upcontent.charAt(i);25 //isLetter()確定指定字符是否為字母。26 if (Character.isLetter(c)) { //等價于c>='A'&&c<='Z'27 arr[c-'A']++;28 }29 }30 ServletContext context = getServletContext();31 context.setAttribute("arr", arr);32 RequestDispatcher rd =context.getRequestDispatcher("/servlet/result");33 rd.forward(request, response);34 }35 36 public void doPost(HttpServletRequest request, HttpServletResponse response)37 throws ServletException, IOException {38 39 doGet(request, response);40 41 }42 }統(tǒng)計字母次數(shù):CountForA_Z
1 package com.shellway.servletcontext; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletContext; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 public class CountForResult extends HttpServlet {13 14 public void doGet(HttpServletRequest request, HttpServletResponse response)15 throws ServletException, IOException {16 ServletContext sc = getServletContext();17 int []arr1 = (int[])sc.getAttribute("arr");18 char c = 0 ;19 response.setContentType("text/html;charset=utf-8");20 PrintWriter pw =response.getWriter();21 for (int i = 0; i < arr1.length; i++) {22 c = (char) (i+'A');23 pw.write(c+"出現(xiàn)的次數(shù)為: "+arr1[i]+" 次"+"<br/>");24 }25 }26 27 public void doPost(HttpServletRequest request, HttpServletResponse response)28 throws ServletException, IOException {29 30 doGet(request, response);31 32 }33 }統(tǒng)計字母次數(shù):CountForResult4、利用ServletContext對象讀取資源文件
使用java application 讀取文件,讀取當(dāng)前工程下所有文件 ----- 使用相對路徑讀取文件使用Servlet讀取文件 只能讀取WebRoot下所有文件 ---- 必須使用絕對磁盤路徑讀取文件
通過站點根目錄絕對路徑 獲得磁盤絕對路徑 ------ getServletContext().getRealPath(“/WEB-INF/info.txt”)
* 因為 WEB-INF/classes 非常特殊 (存放.class文件目錄),被類加載器加載,通過Class類對象讀取 該目錄下文件 String filename3 = c.getResource("/a1.txt").getFile(); ----- / 代表 /WEB-INF/classes
結(jié)論:在web工程中,必須將 文件路徑轉(zhuǎn)換絕對磁盤路徑 c:/xxx e:/xxx/xxx ----- getServletContext().getRealPath("/xxx"); /代表WebRoot 如果讀取文件 恰好位于 WEB-INF/classes ----- 通過 類名.class.getResource("/文件名").getFile(); 獲得絕對磁盤路徑 / 代表 /WEB-INF/classes


1 package com.shellway.io; 2 3 import java.io.BufferedReader; 4 import java.io.FileNotFoundException; 5 import java.io.FileReader; 6 import java.io.IOException; 7 8 public class ReadFile { 9 public static void main(String[] args) throws Exception {10 String fileName = "src/a1.txt";11 readfile(fileName);12 13 String fileName2 = "WebRoot/a2.txt";14 readfile(fileName2);15 16 String fileName3 = "a3.txt";17 readfile(fileName3);18 }19 20 private static void readfile(String fileName) throws FileNotFoundException,21 IOException {22 BufferedReader in = new BufferedReader(new FileReader(fileName));23 String len;24 while ((len = in.readLine())!=null) {25 System.out.println(len);26 }27 }28 }使用java application 讀取上圖中文件a1,a2,a3
1 package com.shellway.io; 2 3 import java.io.BufferedReader; 4 import java.io.FileNotFoundException; 5 import java.io.FileReader; 6 import java.io.IOException; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet;10 import javax.servlet.http.HttpServletRequest;11 import javax.servlet.http.HttpServletResponse;12 13 public class ReadFileServlet extends HttpServlet {14 15 public void doGet(HttpServletRequest request, HttpServletResponse response)16 throws ServletException, IOException {17 String fileName = "/a2.txt";//這里的/代表網(wǎng)站的根目錄18 String s = getServletContext().getRealPath(fileName);19 //返回: D:/apache-tomcat-6.0.14/webapps/day03/a2.txt20 System.out.println(s);21 readfile(s);22 23 String fileName2 = "/a1.txt";//這里的/代表classpath根路徑,即: /WEB-INF/classes24 String s2 = ReadFileServlet.class.getResource(fileName2).getFile();25 //返回: /D:/apache-tomcat-6.0.14/webapps/day03/WEB-INF/classes/a1.txt26 System.out.println(s2);//27 readfile(s2);28 }29 30 private static void readfile(String fileName) throws FileNotFoundException,31 IOException {32 BufferedReader in = new BufferedReader(new FileReader(fileName));33 String len;34 while ((len = in.readLine()) != null) {35 System.out.println(len);36 }37 }38 39 public void doPost(HttpServletRequest request, HttpServletResponse response)40 throws ServletException, IOException {41 42 doGet(request, response);43 44 }45 }使用Servlet讀取文件 只能讀取WebRoot下所有文件。只能讀取/WEB-INF下的a2和類路徑下的a1,而a3讀取不了缺省Servlet 功能:處理其他Servlet都不處理請求 tomcat/conf/web.xml org.apache.catalina.servlets.DefaultServlet 作為缺省Servlet
總結(jié):1、編寫Servlet HelloServlet2、修改Servlet模板 3、Servlet生命周期 理論重點掌握4、Servlet url三種寫法 完全、目錄、擴(kuò)展名5、路徑問題:絕對路徑 ----- 案例 九九乘法表將web.xml 配置路徑復(fù)制到網(wǎng)頁 在路徑前 /工程名6、ServletConfig 和ServletContext 讀取初始化參數(shù)區(qū)別 ?7、ServletContext數(shù)據(jù)共享案例 ----- 統(tǒng)計訪問次數(shù)8、ServletContext轉(zhuǎn)發(fā)案例 --- 統(tǒng)計字母出現(xiàn)次數(shù)9、讀取web工程中資源文件 ---- 絕對路徑在web工程中,必須將 文件路徑轉(zhuǎn)換絕對磁盤路徑 c:/xxx e:/xxx/xxx ----- getServletContext().getRealPath("/xxx"); /代表WebRoot 如果讀取文件 恰好位于 WEB-INF/classes ----- 通過 類名.class.getResource("/文件名").getFile(); 獲得絕對磁盤路徑 / 代表 /WEB-INF/classes 10、缺省Servlet 了解功能將靜態(tài)資源數(shù)據(jù)內(nèi)容讀取寫給客戶端
新聞熱點
疑難解答