servlet總結(jié)1
servlet 總結(jié)ServletC/S--->Client/Server(客戶機(jī)/服務(wù)器)優(yōu)點(diǎn):1)運(yùn)行效率較高2)交互性強(qiáng)適合局域網(wǎng),缺點(diǎn):升級維護(hù)困難B /S -->Browser/Server
servlet 總結(jié)
Servlet
C/S--->Client/Server(客戶機(jī)/服務(wù)器)
優(yōu)點(diǎn):
1)運(yùn)行效率較高
2)交互性強(qiáng)適合局域網(wǎng),
缺點(diǎn):升級維護(hù)困難
B /S -->Browser/Server(瀏覽器/服務(wù)器)
優(yōu)點(diǎn):無需關(guān)心客戶端, 升級維護(hù), 只需操作服務(wù)器即可. 比較方便.
缺點(diǎn):
1) 交互性是請求/響應(yīng)式, 需要通過網(wǎng)絡(luò)進(jìn)行交互, 效率相對c/s架構(gòu)的軟件來說較低.
2) 要開發(fā)交互性較強(qiáng)的界面比較困難.
CGI:最早開發(fā)b/s架構(gòu)的一門技術(shù)
從CGI 分出 1) 微軟的ASP--->ASP.NET
2)JAVA 的Servlet--->jsp
開發(fā)技術(shù):
靜態(tài)網(wǎng)頁技術(shù):
HTML,JS,CSS
動態(tài)網(wǎng)頁技術(shù):(動態(tài)說的是數(shù)據(jù)動態(tài))
CGI,ASP,ASP.net,servlet,php,jsp 等
url:
協(xié)議://地址(ip-->域名):端口(如果是80, 可以省略)/web應(yīng)用名/資源名
web 服務(wù)器: (微軟的)IIS:
(apache的)tomcat(開源的):等..
servlet:
1) 屬于j2ee 的其中一個技術(shù), 是一個規(guī)范
2)servlet 是一個web 組件(包含servlet 類和他的描述信息) 組件如java bean 可復(fù)用的
3)servlet 運(yùn)行的時候就是一個java 對象(創(chuàng)建. 調(diào)用. 管理由web 服務(wù)器(web容器) 完成).web 容器是web 服務(wù)器的線程 tomcat 的web 容器是CATALINA
web 容器調(diào)用servlet 對象的方法
首先由web 容器創(chuàng)建兩個對象:
,1.HttpServletRequest:
包含了客戶端提交的所以信息, 在servlet 中 , 可以通過這個對象獲得客戶端傳遞過來的數(shù)據(jù).
2.HttpServletResponse:
通過這個對象可以向客戶端返回數(shù)據(jù)
public void service(ServletRequest req,ServletResponse res){
}
web 應(yīng)用的目錄結(jié)構(gòu):
應(yīng)用名:(web應(yīng)用的根目錄的名字)
WEB-INF(必須):瀏覽器不能直接訪問
classes(存放.class 文件)
lib(存放第三方的.jar 文件)
web.xml(描述servlet, 包括類名和訪問標(biāo)識)
html/first.html
js/my.js
css/my.css
jsp/first.jsp
META-INF
tomcat 服務(wù)器的目錄結(jié)構(gòu):
bin:存放一些可執(zhí)行文件:比如startup.sh,shutdown.sh
common:存放tomcat 服務(wù)器和所以web 應(yīng)用都可以使用的類和jar 包
conf:存放tomcat 服務(wù)器使用的一些配置文件. 比如 service.xml 中可改端口號
logs:存放tomcat 服務(wù)器和web 應(yīng)用輸出的日志信息的文件
server:存放一些只能由tomcat 服務(wù)器使用的類和jar 包, 以及tomcat 自帶的web 應(yīng)用 shared:存放一些只能由web 應(yīng)用使用的類和jar 包
temp:存放一些臨時文件
*webapps:用來部署web 應(yīng)用
work:存放jsp 文件被翻譯和編譯以后的.java 和.class 文件.
web 工程(IDE):通過工程可創(chuàng)建web 應(yīng)用
web 應(yīng)用:(成品軟件)
javax.servlet.Servlet(接口)
javax.servlet.GenericServlet(抽象類)
javax.servlet.http.HttpServlet(抽象類)(建議使用)
Service-->doGet/doPost(根據(jù)客戶端請求方式調(diào)用, 不是非要同時調(diào)用)
,tomcat 由于已經(jīng)啟動無法啟動 用命令 ps -ef|grep tomcat 在kill -9 進(jìn)程號
form 表單處理:
1. 提供表單
a) 提供一個html 頁面包含一個form 表單
b) 提供一個servlet 返回一個form 表單
form 表單action 屬性指定的路徑
a) 相對路徑
register
b) 絕對路徑
/servlet/form/register
2. 中文亂碼問題
a )get 方式提交
解決辦法,在服務(wù)器中設(shè)置客戶端提交請求的URI 的編碼類型
在server.xml 中 b )post 方式提交 在server 中獲得客戶端提交的參數(shù)之前,調(diào)用req 對象的setCharacterEncoding 方法設(shè)定編碼類型。 c )響應(yīng) 在server 中獲得輸出流之前,調(diào)用response 對象的的setCharacterEncoding 方法設(shè)定編碼類型。 3.method="get"和method="post" (form表單的兩種提交方式比較) get 請求: a) 直接在瀏覽器地址欄輸入請求的URL 發(fā)起的請求: b) 點(diǎn)擊一個超連接發(fā)起的請求 c) 提交一個form 表單但form 表單的method 不指定或指定get 的時候 特點(diǎn): 提交的數(shù)據(jù)放在請求的頭部, 一般在查詢數(shù)據(jù)的時候我們會選擇get 方法發(fā)起請求 post 請求: a) 提交一個method 屬性指定為post 的表單發(fā)起的請求. 特點(diǎn): 提交的數(shù)據(jù)放在請求體部, 在向客戶端提交數(shù)據(jù)的時候我們會選擇使用post 方式發(fā)起請求. 4.request/response對象中的方法 request.getContextPath();返回web 的應(yīng)用的根路徑 request.getMethod();返回請求方式,get 或post request.getParameterMap();獲得客戶端提交的所有參數(shù), 包括參數(shù)名字和值 request.getParameterNames();獲得客戶端參數(shù)名字 request.getQueryString();返回URI 后面所跟著的參數(shù) 如果是post 方式提交返回null request.setCharacterEncoding("UTF-8");設(shè)定客戶端提交的內(nèi)容的編碼類型 5.servlet 的url-pattern 的寫法(補(bǔ)充) a) 以"/"開始, 后面跟著具體的內(nèi)容 b) 前通配(*) :如 *.do,*.action c) 后通配 如: /form/*,/basic/* Servlet 的生命周期(四個階段) 1) 裝載和實例化階段 創(chuàng)建者:web容器 創(chuàng)建情況: (1)第一次訪問的時候創(chuàng)建 當(dāng)num<0時, 第一次訪問時創(chuàng)建servlet 實例 (2)web應(yīng)用被安裝的時候創(chuàng)建(啟動服務(wù)器) 當(dāng)num >=0時,servlet 在web 應(yīng)用被安裝的時候創(chuàng)建 創(chuàng)建順序: num=0,最晚被創(chuàng)建 num>0,值越小越早被創(chuàng)建 2) 初始化階段 調(diào)用者:web容器 public void init(ServletConfig config){} 在GenericServlet 中已經(jīng)對有參的init 方法作了實現(xiàn) public abstract class GenericServlet implement Servlet{ private ServletConfig config; public void init(ServletConfig config){ this.config=config; this.init(); } public void init(){ } } 3) 服務(wù)階段 調(diào)用者:web容器 public void service(ServletRequest req,ServletResponse res){ } 在HttpServlet 中已經(jīng)對service 方法作了實現(xiàn) public abstract class HttpServlet extends GenericServlet{ public void service(ServletRequest req,ServletResponse res){ HttpServletRequest hReq=(HttpServletRequest)req; HttpServletResponse hRes=(HttpServletResponse)res; service(hReq,hRes); } public void service(HttpServletRequest hReq, HttpServletResponse hRes){ String method=hReq.getMethod(); if(method.equals("GET")){ doGet(hReq,hRes); }else if(method.equals("POST")){ doPost(hReq,hRes); } } //被子類覆蓋 public void doGet(HttpServletRequest request, HttpServletResponse response) { } //被子類覆蓋 public void doPost(HttpServletRequest request, HttpServletResponse response){ } } 4) 銷毀階段 調(diào)用者:web容器 public void destory{ } 注:init(),service(),destroy()稱為servlet 對象的生命周期回掉方法. web 應(yīng)用的邏輯分層: model(模型): javabean,ejb.. view(顯示): servlet,jsp 等 control(控制): servlet,jsp.... 請求的轉(zhuǎn)發(fā): 1) 服務(wù)器內(nèi)部跳轉(zhuǎn) 請求轉(zhuǎn)發(fā)器:RequestDispather 創(chuàng)建: 1. 調(diào)用request 對象的方法 指定的轉(zhuǎn)發(fā)路徑可以相對也可以是絕對的 相對路徑:根據(jù)當(dāng)前servlet 的路徑和轉(zhuǎn)發(fā)的路徑進(jìn)行計算 絕對路徑:就是轉(zhuǎn)發(fā)的servlet 的url-pattern 2. 調(diào)用servletContext 對象的方法 指定的路徑必須是絕對路徑 forward: 在轉(zhuǎn)發(fā)請求之前首先調(diào)用response 對象的resetBuffer 方法, 清空緩存. include(包含): 將請求轉(zhuǎn)發(fā)到其他servlet 之前不會清空緩存 2) 服務(wù)器外部重定向 RedirectServlet 通過服務(wù)器外部重頂向進(jìn)行請求的轉(zhuǎn)發(fā) 里面的路徑可以相對可以絕對 絕對路徑寫法: 應(yīng)用根路徑 servlet的url-pattern 例:response.sendRedirect(request.getContextPath() "/resource/view"); 相對路徑寫法:例:response.sendRedirect("view"); 服務(wù)器內(nèi)部跳轉(zhuǎn)和服務(wù)器外部重定向的比較 1) 服務(wù)器內(nèi)部跳轉(zhuǎn)所有的servlet 共享同一個請求, 而服務(wù)器外部重定向, 每個Servlet 接受的請求都不相同 2) 服務(wù)器內(nèi)部跳轉(zhuǎn)是在服務(wù)器實現(xiàn)的, 而服務(wù)器外部重定向是由瀏覽器實現(xiàn)的 3) 服務(wù)器內(nèi)部跳轉(zhuǎn)是通過request 對象來完成的, 而服務(wù)器外部重定向是通過response 對象來完成的. 作業(yè): 1.findUser.html 2.FindUserServlet: 1. 負(fù)責(zé)接收客戶端查找用戶的請求 2. 調(diào)用UserMange 的findUser(String name) 3. 將找到的User 對象交給ViewUserServlet 顯示 ViewUserServlet 1. 首先判段有沒有需要顯示的user, 如果沒有 提示 2. 如果有, 則將用戶的詳細(xì)信息進(jìn)行顯示 3. 在UserManager 中提供查詢用戶的方法. Context ctx=new InitialContext(); DataSource ds=(DataSource)ctx.lookup(jndiName); 通過jndi 從目錄服務(wù)器上查找DataSource 對象 DataSource( 連接池); 06 02 2008 JNDI:java name directory interface 創(chuàng)建DataSource 對象 1. 通過new 的方式創(chuàng)建. 2. 通過web 服務(wù)器提供的配置的方式, 來創(chuàng)建DataSource(這種方式創(chuàng)建的DataSource 已經(jīng)存放在目錄服務(wù)器上). 1) 將oracle 的驅(qū)動包放入到tomcat 的common/lib目錄下 2)JNDI Name:jdbc/ds 數(shù)據(jù)庫的URL Data Source URL:jdbc:oracle:thin:@192.168.1.220:1521:briupdb 數(shù)據(jù)庫驅(qū)動名:JDBC Driver Class:oracle.jdbc.driver.OracleDriver 數(shù)據(jù)庫用戶名:User Name:jd0804 數(shù)據(jù)庫用戶密碼:Password:jd0804 最大活動的連接數(shù):Max. Active Connections: Max. Idle Connections:(當(dāng)連接池沒有連接的時候, 再創(chuàng)建的連接數(shù)) 使用DataSource 1. 如果是通過new 的方式創(chuàng)建的DataSource, 可以直接調(diào)用他的getConnection 方法來獲得連接 2. 通過jndi 訪問目錄服務(wù)器, 查找DataSource, 調(diào)用方法獲得連接. ch05 狀態(tài)持久。 為什么需要狀態(tài)持久? 因為http 協(xié)議是無狀態(tài)的, 客戶端發(fā)起一個請求的時候, 會跟服務(wù)器建立socket 連接, 一旦響應(yīng), 就會關(guān)閉socket 連接, 所以為了讓服務(wù)器端知道某個客戶端的狀態(tài)信息, 我們需要將狀態(tài)進(jìn)行持久化 cookie 創(chuàng)建: name value Cookie cookie = new Cookie("isLogin", "true"); cookie.setMaxAge(time); response.addCookie(cookie); 當(dāng)time<0,表示cookie 保存在瀏覽器進(jìn)程中, 一旦瀏覽器進(jìn)程結(jié)束,cookie 就消失 當(dāng)time=0,表示刪除客戶端同名的cookie 當(dāng)time>0,表示cookie 將在瀏覽器端保存起來, 超過time 后才會消失 獲取: Cookie[] cookies=request.getCookies(); session(結(jié)合cookie 使用):創(chuàng)建和保存都在服務(wù)器端 由web 服務(wù)器維護(hù) HttpSession session = request.getSession(); 或者 HttpSession session = request.getSession(boolean create); 當(dāng)create==true時, 這個方法的作用跟無參的getSession()方法作用一樣 當(dāng)create==false時, 這個方法的作用是:根據(jù)客戶端傳遞過來的session 的id, 尋找服務(wù)器端的session, 如果找到返回, 如果沒有找到, 返回null; String ID=session.getId(); session.setAttribute("isLogin", true); 當(dāng)對客戶端作出響應(yīng)的時候,會將session 的ID 包裝成一個cookie 對象(名字為JSESSIONID ,值為session 的id ),返回給客戶端 HttpSession 消失的情況: 1)web 應(yīng)用停止 2) 超時(上一次訪問開始的時間到當(dāng)前時間, 如果這個時間超過了指定的超時時間, 那么就認(rèn)為是超時了) 可在web.xml 中可配置session 的超時時間: 3) 調(diào)用session 對象的invalidate 方法 通過URL 重寫解決cookie 禁用sesion 不能訪問的問題: 當(dāng)客戶端禁用cookie 之后,無法通過cookie 保存session 的id 我們可以通過URL 重寫來保存session 的id url ;jsessionid=HJGKJWBDRUWRGW String oldUrl = "sessionCheck"; String newUrl = response.encodeURL(oldUrl);// encodeUrl已不建議使用 三個范圍(scope ) requestScope(ServletRequest):在多個servlet 之間進(jìn)行服務(wù)器內(nèi)部跳轉(zhuǎn)的時候,我們可以通過將數(shù)據(jù)放在request 對象中進(jìn)行數(shù)據(jù)的傳遞。 request.setAttribute(key,value); Object value=request.getAttribute(key); request.removeAttribute(key); sessionScope(HttpSession):session中一般存放一些狀態(tài)信息,或者在整個會話中經(jīng)常要使用的數(shù)據(jù)(不建議存放過多數(shù)據(jù)(影響服務(wù)器效率)) session.setAttribute(key,value); Object value=session.getAttribute(key); session.removeAttribute(key); applicationScope(ServletContext):ServletContext一般存放整個系統(tǒng)運(yùn)行過程中,經(jīng)常要使用的數(shù)據(jù) ctx.setAttribute(key,value); Object value=ctx.getAttribute(key); ctx.removeAttribute(key); 過濾器:Filter web 應(yīng)用的事件的處理機(jī)制 1. 事件源 web 容器 2. 事件對象:由web 容器創(chuàng)建 在web 應(yīng)用啟動和停止的時候產(chǎn)生:ServletContextEvent 在javax.servlet 包中 會話開始和結(jié)束的時候產(chǎn)生:HttpSessionEvent 在javax.servlet.http 包中 請求開始和結(jié)束的時候:ServletRequestEvent 對application 范圍中的數(shù)據(jù)操作的時候產(chǎn)生:ServletContextAttributeEvent 對session 范圍內(nèi)的數(shù)據(jù)進(jìn)行操作的時候產(chǎn)生: HttpSessionBindingEvent 對requset 范圍中的數(shù)據(jù)操作進(jìn)行操作的時候產(chǎn)生: ServletRequestAttributeEvent 3. 監(jiān)聽器 處理ServletContextEvent 事件對應(yīng)ServletContextListener 接口(執(zhí)行時間:web應(yīng)用啟動和停止) 處理HttpSessionEvent 事件 HttpSessionListener 執(zhí)行時間:session(會話) 開始和結(jié)束 處理ServletRequestEvent 事件 ServletRequestListener 執(zhí)行時間:請求的開始和結(jié)束 處理ServletContextAttributeEvent 事件 ServletContextAttributeListener 執(zhí)行時間:加入數(shù)據(jù), 刪除數(shù)據(jù), 替換數(shù)據(jù) HttpSessionBindingEvent HttpSessionAttributeListener 執(zhí)行時間:加入數(shù)據(jù), 刪除數(shù)據(jù), 替換數(shù)據(jù) ServletRequestAttributeEvent ServletRequestAttributeListener 執(zhí)行時間:加入數(shù)據(jù), 刪除數(shù)據(jù), 替換數(shù)據(jù) 注冊監(jiān)聽器:在web.xml 中描述就可以完成監(jiān)聽器的工作. 一、 過濾器 Filter 1. why Filter? 針對通用WEB 服務(wù)、功能,透明的處理 2. 什么是 Servlet Filter? 過濾是 Servlet 2.3 版才引入的新特性。過濾器可以認(rèn)為是實現(xiàn) Http 請求、響應(yīng)以及頭信息等內(nèi)容的傳送的代碼片斷。 過濾器并不能創(chuàng)建響應(yīng),但它可以“過濾”傳給 servlet 的請求,還可以“過濾”從 servlet 發(fā)送到客戶端的響應(yīng); 它不僅能處理靜態(tài)內(nèi)容,還可以處理動態(tài)內(nèi)容。換而言之,filter 其實是一個“servlet chaining”(servlet 鏈) 。 一個 filter 包括: 1) 在 servlet 被調(diào)用之前截獲; 2) 在 servlet 被調(diào)用之前檢查 servlet request; 3) 根據(jù)需要修改 request 頭和 request 數(shù)據(jù); 4) 根據(jù)需要修改 response 頭和 response 數(shù)據(jù); 5) 在 servlet 被調(diào)用之后截獲. 3. 過濾器的生命周期 Filter 組件的生命周期與 Servlet 的類似。 過濾器有四個階段(與servlet 類似) : 1) 實例化; 2) 初始化(調(diào)用init()方法); 3) 過濾(調(diào)用doFilter()方法); 4) 銷毀(調(diào)用destroy()方法); 4. Filter編程 1) 定義Filter(implements Filter) 2) 配置Filter 配置對哪些資源進(jìn)行過濾(url)