上下文對象-請求對象-響應對象(ServletContext - response - request)


上下文對象-請求對象-響應對象

ServletContext

什么是ServletContext

  • ServletContext代表是一個web應用的上下文對象(web應用對象)
  • 里面封裝的都是web應用信息
  • 一個ServletContext對應一個應用

ServletContext的生命周期

  • 在服務器一啟動的時候就會創建
  • 在服務器關閉的時候銷毀

如何獲得上下文

​ 1.通過init方法當中一個參數ServletConfig來獲取
​ 2.直接在HttpServlet當中獲取

  • this.getServletContext

  • 這種方法本質還是通過config來去獲取的​

獲取全局的初始化參數

  • 初始化參數不能再某一個Servlet當中來去配置。在最外層來去配置

  • 獲取全局初始化參數

獲得Web應用中某一個資源的資源的絕對路徑

  • context.getRealPath("文件")
  • 相對的是web應有根目錄

​ context.getRealPath("index.html")
​ D:\Java\Tomcat\apache-tomcat-7.0.85\webapps\bei\index.html
​ 在你寫的名稱前面自動拼接上當前工程的絕對地址

ServletContext是一個域對象

什么是域?
  • 能夠存儲數據
域對象
  • 能夠存取數據流的對象
ServletContext域對象的作用范圍
  • 整個web應用
  • 所有的web資源都可以進行存取數據
  • 數據是可以共享的
獲取完ServletContext之后向里面寫數據

​ context.setAttribute(String name,Object value);

獲取完ServletContext之后,通過name取出存放的數據

​ context.getAttribute(String name);

獲取完ServletContext之后,刪除指定名稱的值

​ Context.removeAttribute(String name);

response

response響應過程

  • 在去發送一個請求時, 會找到tomcat引擎
  • 引擎會找到對應的web應用
  • 並且會創建request對象和response對象
  • 找到應用后, 會執行應用的web.xml再去根據url-pattern的內容創建Servlet對象
  • 並且會調用Servlet對象的service方法,把創建的request對象和response對象傳入到方法當中
  • 拿到response對象后, 自己可以往響應當中寫入一些自己給客戶端的內容
  • 通過response.getwrite().wirte("寫的內容")方法進行寫入
  • 寫的內容,是存到一個response緩沖區當中
  • 當方法執行結束之后, tomcat就會從response緩沖區當中取出數據
  • 取出你的數據同時,它自己還會自動的往里面添加一些服務器相關的信息進去
  • 所以響應給瀏覽器時, 可以看到除了自己寫的內容, 還會有一些服務器相關的信息

​ 流程圖

通過response設置響應行,響應頭 ,響應體

設置響應行

​ response.setState(Int code)

設置響應頭
add
  • add代表添加新的內容
  • addHeader(String name,String value)
  • addIntHeader(String name,int value)
  • addDateHeader(String name,date)

set
  • set代表設置,已經存在的內容
  • setHeader(String name,String value)
  • setIntHeader(String name,int value)
  • setDateHeader(String name,Date value)
  • 添加兩個相同的name

重定向

​ 什么是重定向

  • 到服務器當中去找servlet1
  • servlet1當中沒有這個資源,告訴你去找servlet2
  • 再去發送一個請求到servlet2

​ 狀態碼
​ 302
​ 特點
​ 1.要訪問兩次服務器

  • 第一次訪問是人為的去訪問
  • 第二次是自動的訪問

​ 2.瀏覽器地址欄已經發生變化
​ 設置重定向

  • 設置響應碼

  • 設置響應頭

封裝的重寫向

  • 每次都要寫狀態碼,和location比較麻煩

  • 就給封裝了一個方法 response.sendRedirect("/bei/servlet2")

    定時刷新重定向
    ​ ​ response.setHeader("refresh","5;url=http://www.baidu.com")

  • 5代表5秒

  • url的值為5秒后要去跳轉的地址​

設置響應體
1.通過write方法來寫

​ response.getwrite().wirte(“要寫的內容”)
​ ​ 默認情況下寫的中文內容會亂碼
​ ​ 把寫的內容存到緩存區中使用的是ISO8859
​ ​ ISO8859不支持中文,所以會亂碼
​ ​ 在存之前設置可以設置存放的編碼
​ ​ response.setCharacterEncoding("UTF-8")
​ ​ 告知瀏覽器使用的是utf-8編碼
​ ​ response.setHeader("Content-Type", "text/html;charset=UTF-8");

​ ​
​ ​ 上面代碼只需要寫第二句就行, tom看到設置了為utf-8的編碼,它在存在的時候也會使用utf-8的編碼
​ ​ 使用封裝寫法
​ ​ response.setContentType("text/html;charset=UTF-8");

2.通過OutPutStream來寫

​ ​ FileInputSteam

​ ​ read方法讀取一個字節

​ ​ read(byte[] b)

  • 一次讀取多個字節,並存放到數組b中
  • 上面是一次一滴一滴給你,這種是一次裝一水桶再給你

​ ​ 讀取全部的數據

​ ​ FileOutputSteam

write()
一次性寫一個字符
write(buffer)
一個性寫多個字符
write(buffer,0,len)
一次性寫指定個數的字符

​ ​ response注意點

​ ​ getWrite()和getOutputSteam不能同時調用

下載功能

​ ​ 下載文件
​ ​ 1.直接使用a標簽來去下載,存在的問題

  • 有些內容會瀏覽器自動解析
  • 瀏覽器不能解析的文件才會被下載

​ ​
​ ​ 2.通過發送Servlet請求來去下載
​ ​

通過發送一個Servlet請求,把文件名發送給服務器
發送給服務器后,接收到文件名參數,獲取文件的絕對地址
通過流的形式來去寫到瀏覽器
還得要告訴文件是什么類型
​	瀏覽器是以MIME的類型來識別類型
​		this.getServletContext().getMimeType(“文件名稱”)
​	設置響應的類型
​		res.setContentType("MIME類型")
設置響應頭,告訴瀏覽器不要去解析,是以附件的形式打開,
​	res.setHeader("Content-Dsiposition","attachment;filename="+文件名)
步驟
1.接收文件名參數
2.獲取mime類型
3.設置瀏覽器響應類型
4.告訴瀏覽器以附件形式下載
5.獲取文件的絕對路徑
6.讀取文件流
7.獲取輸出流
8.把內容寫出到輸出流

//1.接收文件名參數
String filename = request.getParameter("filename");
String mime = this.getServletContext().getMimeType(filename);
response.setContentType(mime);
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//2.獲取文件的絕對路徑
String path = this.getServletContext().getRealPath("download/"+filename);
System.out.println(path);
//3.讀取文件流
FileInputStream in = new FileInputStream(path);
//4.獲取輸出流
ServletOutputStream out = response.getOutputStream();
//5.把內容寫出到輸出流
byte[] buffer = new byte[1024];
int len = 0;
while((len = in.read(buffer)) != -1) {
	out.write(buffer, 0, len);
}
解決中文名稱亂碼問題
獲取中文參數報錯問題
    			高版本tomcat中的新特性:就是嚴格按照 RFC 3986規范進行訪問解析,而 RFC 3986規范定義了Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字符以及所有保留字符(RFC3986中指定了以下字符為保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])
    			.../conf/catalina.properties中,找到最后注釋掉的一行 #tomcat.util.http.parser.HttpParser.requestTargetAllow=|  ,改成tomcat.util.http.parser.HttpParser.requestTargetAllow=|{},表示把{}放行
    		1.把獲取的字符串參數的字節碼獲取,再重新使用utf-8編碼
    		2.在設置以附件形式打開時, 不同的瀏覽器會對默認的名字進行解碼
    		所以根據不同的瀏覽器,要對名稱進行編碼之后,再放入文件名
    		對文件名進行編碼
    			不同的瀏覽器編碼不一樣
    			要先獲取agent,取出瀏覽器的類型
                根據不同的瀏覽器類型進行編碼
                步驟
                1.接收文件名稱
                2.獲取mimeType
                3.設置瀏覽器響應類型
                4.先對傳入的參數轉成二進制流,再使用UTF-8進行編碼
                5.獲取瀏覽器的信息
                6.判斷是哪一種瀏覽器,根據不同的瀏覽器獲取一個編碼的文件名
                7.設置以附件形式下載,傳的名稱是編碼過的名稱 
                8.獲取文件的絕對路徑
                9.讀取文件流
                10.獲取輸出流
                11.把文件寫到響應當中

// 獲取客戶端信息
String agent = request.getHeader("User-Agent");
// 定義一個變量記錄編碼之后的名字
String filenameEncoder = "";
if (agent.contains("MSIE")) 
{
	// IE編碼
	filenameEncoder = URLEncoder.encode(filename, "utf-8");
	filenameEncoder = filenameEncoder.replace("+", " ");
} 
else if (agent.contains("Firefox")) 
{
	// 火狐編碼
	BASE64Encoder base64Encoder = new BASE64Encoder();
	filenameEncoder = "=?utf-8?B?" + 	base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} 
else 
{
	// 瀏覽器編碼
	filenameEncoder = URLEncoder.encode(filename, "utf-8");
}

注冊驗證碼功能

​ 1.把別人寫好的驗證碼Servlet拿到程序當中

​ 2.編寫靜態頁面

​ 3.編寫判斷驗證碼是否正確Servlet

​ 1.設置響應編碼
​ 2.從ServletContext當中獲取驗證碼
​ 3.獲取傳入的請求參數
​ 4.從servletContext當中取出存放的驗證碼
​ 5.把接收的驗證碼與取出的驗證碼時行比較
​ 6.相同時,顯示成功
​ 7.不同時, 顯示失敗,隔3秒鍾跳轉到輸入驗證碼界面

request

如何獲取請求行, 請求頭,請求體

獲取請求行

​ 獲取請求方法
​ String getMethod()

獲取請求資源

​ String getRequestURL()

​ String getRequestURI()

獲取應用名稱

​ String getContextPath()

獲取get查詢參數

​ String getQueryString()

獲取請求頭
1.獲取所有的請求頭名稱

2.獲取指定的頭信息


3.打印所有的請求頭和請求頭內容

referer

​ 告訴服務器我是從哪個頁面鏈接過來的

​ 注意事項
​ 通過以下方式發送請求才會獲取

​ 通過以下方式不會有referer

  • 從收藏夾鏈接
  • 單擊主頁或自定義的地址
  • 在瀏覽器中直接輸地址
獲取請求體

​ 1.獲取一個值
​ req.getParameter("名稱")

​ 2.獲取多個值
​ req.getParameterValues("名稱")
​ 返回的是一個數組

​ 3.獲取所有請求參數名稱
​ req.getParameterNames()
​ 返回的是一個枚舉

​ 4.獲取所有請求參數
​ req.getParameterMap()
​ 獲取所有請求參數的key-value集合Map<String,String[]>

解決中文亂碼問題

​ 什么時候使用get方式與post方式
​ 1.發送的參數不需要寫到數據庫當中使用get
​ 2.發送的參數需要保存到數據庫當中使用post
​ form一般提交數據的數據為post
​ 造成亂碼的原因
​ 發送請求時, 會對參數進行編碼,編碼使用的是ISO8859-1 不支持中文,所以亂碼
​ 通用解決辦法
​ 獲取對應的參數
​ 通過iso8859-1轉回二進制位,再以utf-8的形式轉成字符串
​ 存在的問題,每一個參數都必須得要轉回二進制位,再轉為字符串
​ request方法解決中文亂碼
​ 只適用於post

請求轉發
重定向與請求轉發的區別

​ 重定向

  • 找servlet1,通過設置響應,告訴瀏覽器, 再讓瀏覽器發送請求到servlet2
  • 發兩次請求
  • 地址欄會發生變化

​ 請求轉發

  • 請求轉發只需要發送一次直接,找servlet1,在servlet1當中直接轉發給servlet2,不要再告訴瀏覽器
  • 只發送一次請求
  • 瀏覽器地址欄當中還是servlet1,不會發生變化
實現轉發

​ 1.通過請求對象獲取一個轉發器

  • request.getRequestDispatcher(String path)
  • 返回一個RequestDispatcher

​ 2.通過轉發器進行轉發

  • 調用轉發器的forward方法進行轉發
  • disp.forward(req,rep)
request域對象
在一次請求過程當中
		request是共享的。在一個servlet當中設置的參數,轉發到另外一個servlet,取出來的是同一個
		生命周期
			創建
				發送一個請求時創建一個request對象
			銷毀
				請求結束,瀏覽器給出響應時,銷毀
			作用范圍
				一次請求當中
客戶端地址與服務器端地址

​ 客戶端地址

  • 客戶端訪問服務器使用的地址
  • 服務器外部地址
  • 在寫的時候要寫上web應用的名稱 /應用名稱/資源

​ 服務器地址

  • 在服務內部當中使用的地址
  • 不需要寫web應用名稱 /資源名稱


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM