ServletConfightml
ServletContextjava
Requestweb
Responseapache
Cookie編程
Session設計模式
上面這些對象(固然不止這些,剩下的對象查閱ServletAPI,不是JavaEEAPI)都是web服務器在條用Servlet時所建立的交給 Servlet的對象,將這些對象的API掌握熟練,就基本上掌握Servlet技術了,剩下的就是你的Java編程功力了,基本都是設計方面的事了。數組
web服務器接受到客戶端的http請求,會針對每一次請求,分別建立一個用於表明請求的request對象和表明相應的response對象。若是須要獲取客戶端的相關信息,就使用request對象,須要向客戶端發送數據,就使用response對象。瀏覽器
這裏的request對象和response對象都不是標準的HTTP協議的請求和響應,而是Web服務器根據標準的HTTP協議的請求和響應,而後再根據Servlet規範(接口)實現的Web對象。緩存
其實Servlet技術就是一套接口,這個接口是由當年的SUN公司指定的,Tomcat是一個web服務器,也是Servlet和JSP的容器,爲何它是Servlet與JSP的容器呢,緣由就是它實現了SUN規定的那一套關於Servlet和JSP的規範與接口,因此在查閱ServletAPI時 你會發現,不少都是接口,這是正常的,具體的顯示類是由Tomcat來完成的,咱們只管調用。HttpServletResponse與 HttpServletRequest都是接口。若是你本身編寫了一個服務器,並且實現了Servlet與JSP的接口與規範,那麼你本身編寫的這個服務 器也能夠是Servlet和JSP的容器(不徹底的JAVAEE容器,由於徹底的還須要實現EJB相關接口和規範)。tomcat
Response對象表明響應,一個標準的HTTP響應包含三部分:狀態行、響應頭、響應數據。
經常使用方法有:
setStatus(int sc)
,設置響應的狀態信息
setHeader(java.lang.String name, java.lang.String value)
,設置響應的頭信息
getWriter()
,返回一個PrintWriter對象,給客戶端發送信息
getOutoutStream()
,返回一個ServletOutputStream對象,給客戶端發送流信息
在學習過程當中要注意,學習什麼技術就查什麼文檔,例如如今在學習JavaEE中的Servlet技術,那麼就查閱ServletAPI,不要查閱JavaEEAPI,這樣更加方便,清晰。
向客戶端輸出中文數據
OutputStream向客戶端發送中文數據(默認編碼與設定編碼的問題,亂碼的緣由:客戶端使用系統默認編碼),處理方法:設置響應頭信息
使用HTML語言裏面的<meta>
標籤來控制瀏覽器行爲(模擬一個http響應頭),也能夠解決亂碼問題
使用OutputStream輸出數字1,應該字符化
使用PrintWriter來輸出,設置response的編碼(response默認的編碼問題),還須要告訴瀏覽器(客戶端)以什麼編碼方法打開,使用response的setHeader,簡寫可使用setConteType
文件下載和中文文件的下載
獲取須要下載的文件、通知瀏覽器如下載的方式打開、向瀏覽器寫出數據
若是下載文件的名字是中文,必須使用URL編碼來進行處理
輸出隨機圖片
在內存中建立一張圖片
獲得圖片
設置背景顏色
設置圖片邊框
設置圖片干擾線
向圖片上寫數據
把圖片發送給客戶端
使用中文作驗證
設置瀏覽器不要緩存圖片
定時刷新網頁
使用response的消息頭就可讓瀏覽器定時刷新網頁
使用meta
標籤模擬(<meta http-equiv='refresh' content='3;url=/webapp/index.html'>
)
請求的重定向
重定向與轉發的區別(一個向服務器發了兩次請求,一個向服務器發了一次請求)
重定向發生,地址欄的地址會變化(重定向會增長服務器壓力)
使用 302 狀態碼和 location 頭來完成,也可使用response的重定向跳轉方法來完成
getOutputStream
和getWriter
方法分別用於獲得輸出二進制數據、輸出文本數據的ServletOutputStream和PrintWriter對象
這兩個方法是互斥的,調用了其中的一個,另外一個就不能再調用
在一個請求的整個調用鏈中,只能有一個流存在,若是須要寫多種數據,使用字節流來完成
Servlet引擎在service結束後,會自動檢測response的流是否關閉,若是沒有會自動關閉,而後再銷燬Servlet,可是本身使用的流須要本身手動關閉
HttpServletRequest對象表明客戶端的請求,當客戶端經過HTTP協議訪問服務器時,HTTP請求頭中的全部信息都封裝在這個對象中,經過這個對象,就能夠獲取客戶端的相關信息。
getRequestURL方法返回客戶端發出請求時的完整URL
,資源在互聯網上的位置
getRequestURI方法返回請求行中的資源名部分
,資源的位置
getQueryString 方法返回請求行中的參數部分
getRemoteAddr方法返回發出請求的客戶機的IP地址
,屏蔽IP
getRemoteHost方法返回發出請求的客戶機的完整主機名
,註冊DNS的主機名稱,若是沒有註冊,返回IP
getRemotePort方法返回客戶機所使用的網絡端口號
getLocalAddr方法返回WEB服務器的IP地址
getLocalName方法返回WEB服務器的主機名
getMethod獲得客戶機請求方式
getHead(name)方法
getHeaders(String name)方法
getHeaderNames方法
getParameter(name)方法
getParameterValues(String name)方法
getParameterNames方法
getParameterMap方法
getInputStream方法
防止本身網站的Web資源被別的網站使用。若是你有一個Servet,能夠返回一些Web資源(圖片、文章等等),那麼在別的網站系統中,直接使用<a>
連接,或者發送一個http請求給你的Servlet應用,那麼就能獲取你網站的Web資源。
使用Request對象的getHeader(「referer」)
方法來獲取 referer 信息,rederer能夠告訴咱們當前這個請求是從哪一個網站點擊過來的。
若是沒有使用網頁點擊,而是直接發送的http請求,那麼 rederer 的值爲null
檢測 referer 的開頭是不是本站,並且不能爲 null,不然就重定向到本站首頁
若是須要向服務器發送一系列數據,可使用表單來完成。表單能夠提交表單中的表單元素(表單項)的數據到服務器,瀏覽器會把表單中的可用元素(有 name屬性、disabled屬性不爲false的元素)的值封裝起來。若是表單以get方式提交,那麼這些值就會以 url 參數的形式發送給服務器,若是使用的是 post 方式提交,那麼瀏覽器會將這些數據添加到 http 請求的消息體中(負載)發送給服務器。
常見表單元素:
text
password
radio,若是兩個radio的name相同,就代表它們是一組,每次只會有一個被選中,默認選中使用checked = "checked"
設置,使用 value 值來提交真正的數據
checkbox,多個值的獲取,將多選按鈕的名字都設置能同樣的,在服務端使用 getParameterValues(name)
方法來獲取多個值,返回值是一個數組,使用value值來提交真正的數據
file
select,配合 option 項來提交值,select 元素來設置name,具體的值用 option來設置
textarea,默認值的設置不是用 value ,在標籤體中來設置
hidden,隱藏域
對於表單提交的數據,在服務端必定要作驗證才能使用,否則很容易發生異常
在作web開發時,常常會遇到亂碼的問題,最好的解決亂碼的方式就是從一開始就統一編碼。
若是出現亂碼,首先要分析出現亂碼的緣由,也就是肯定是哪個環節致使了亂碼
通常常見的是:request的默認編碼是 IOS8859-1,而頁面提交的數據(頁面的編碼可使用響應頭和<meta>
標籤來設置,通常推薦UTF-8)不是這個編碼。對於這種編碼通常很好解決,使用 request的 setCharacterEncoding(encoding) 方法來設置 request的編碼就能夠了,可是這種設置僅對 post 方式提交的請求有效
對於以 get 方式提交的請求,在Servlet中處理的話,只能使用手動的轉碼來實現,將 ISO8859-1 轉成響應的編碼。
get 方式提交的請求的亂碼,還有一種方式能夠解決亂碼:改變 Tomcat 的配置(給鏈接器配置一個屬性:URIEncoding=「UTF-8」)。
若是超連接中提交的數據包含中文,必定要進行URL編碼處理
關於get的亂碼解決還有一種方式,就是使用 useBodyEncodingForURI=「true」,這種配置,這個配置的意思是:URI的編碼用request實際設置的編碼,這樣配置 後,request的 setCharacterEncoding(encoding) 對於get請求同樣有效了。
對於改變服務器配置來解決亂碼的方法,在實際開發中並不推薦,不要依賴服務器。
使用request也能夠實現請求的轉發,在實際開發中,使用request作請求轉發的多,通常不使用ServletContext作轉發。若是 在轉發過程當中須要傳值到轉發資源,使用request的setAttribute 方法來傳值,在實際開發中,是使用 request 來進行轉發和傳值的,不使用ServletContext。由於ServletContext都整個Web應用中的Servlet共享,容易出現覆蓋的問 題,而request是獨立的,不存在這個問題。
request也是一個域對象,是一個容器。
請求轉發主要用來實現MVC設計模式。在MVC設計模式中,都是使用Servletl來處理用戶請求,而且產生用戶須要查看的數據,而後轉發給jsp來顯示,轉發給jsp顯示時,會把數據存在request域裏面帶給jsp。
setAttribute 方法
getAttribute 方法
removeAttribute 方法
getAttributeNames 方法
在使用轉發的時候,有些小細節要注意:
若是在調用forward方法以前,在Servlet程序中寫入的部份內容已經被真正傳送到了客戶端,forward方法將拋出參數異常。(好比使用PrintWriter發送數據給客戶端,而後關閉流,而後再使用request來轉發,就會拋異常)
屢次請求轉發也是不可取的,同樣會拋參數異常
關閉response的流,意味着提交響應結果到客戶端,若是不關閉,就沒有提交,仍是有機會作別的響應處理的,那麼別的響應處理將會覆蓋掉以前的響應(以前的響應被清空,可是對於響應頭的設置信息,會保留下來)
總結:在請求轉發的先後,都不要寫數據,寫了也沒有用!!!在Servlet中,只產生數據,可是不作輸出,輸出交給JSP(MVC)
一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理,稱之爲請求轉發
一個web資源收到客戶端請求後,通知瀏覽器去訪問另一個web資源,稱之爲請求重定向
RequestDispatcher.forward方法只能將請求轉發給同一個WEB應用中的組件;而 HttpServletResponse.sendRedirect 方法還能夠重定向到同一個站點上的其餘應用程序中的資源,甚至是使用絕對URL重定向到其餘站點的資源
若是傳遞給HttpServletResponse.sendRedirect 方法的相對URL以「/」開頭,它是相對於整個WEB站點的根目錄;若是建立RequestDispatcher對象時指定的相對URL以「/」開頭,它是相對於當前WEB應用程序的根目錄
調用HttpServletResponse.sendRedirect方法重定向的訪問過程結束後,瀏覽器地址欄中顯示的URL會發生改變, 由初始的URL地址變成重定向的目標URL;調用RequestDispatcher.forward 方法的請求轉發過程結束後,瀏覽器地址欄保持初始的URL地址不變
HttpServletResponse.sendRedirect方法對瀏覽器的請求直接做出響應,響應的結果就是告訴瀏覽器去從新發出對另 外一個URL的訪問請求;RequestDispatcher.forward方法在服務器端內部將請求轉發給另一個資源,瀏覽器只知道發出了請求並得 到了響應結果,並不知道在服務器程序內部發生了轉發行爲
RequestDispatcher.forward方法的調用者與被調用者之間共享相同的request對象和response對象,它們屬 於同一個訪問請求和響應過程;而HttpServletResponse.sendRedirect方法調用者與被調用者使用各自的request對象和 response對象,它們屬於兩個獨立的訪問請求和響應過程
RequestDispatcher.include方法用於將RequestDispatcher對象封裝的資源內容做爲當前響應內容的一部分包含進來,從而實現可編程的服務器端包含功能
被包含的Servlet程序不能改變響應消息的狀態碼和響應頭,若是它裏面存在這樣的語句,這些語句的執行結果將被忽略
在web開發中,常常會使用地址,如:
this.getServletContext().getRealPath("/")
request.getRequestDispatcher("/")
response.sendRedirect("/")
response.getWriter().write("<meta http-equiv='refresh' content='3;url=/'>")
<form aciont="/">
<a href="/">,<img src="">
對於這些地址,裏面均可以用」/「,這些有什麼區別呢?總結:凡是給服務器用的地址,「/「表明當前web應用;凡是給瀏覽器用的地址,「/「表明網站(webapps) 還有」/「與」",前者使用在虛擬路徑或者URL地址;後者使用在硬盤地址。 使用斜槓的地址,都是絕對地址,還有一些狀況是須要相對地址的(後續課程)。