request和response對象

request對象是服務器對瀏覽器請求的封裝,而response是服務器對服務器響應的封裝。
這裏寫圖片描述html

request用來取出請求信息,而response則用來添加要返回給瀏覽器的信息。java

使用response對象設置http響應協議中的信息

用來生成Http響應信息,發送給用戶。數據庫

響應首行數組

HTTP/1.1 200 OK瀏覽器

  • setStatus(int sc):設置正常的響應狀態碼 status code
  • setStatus(int sc, String sm):設置正常的響應狀態碼,狀態碼描述 status message,過期,由於正常狀態下,狀態碼信息不會顯示給用戶,因此沒有必要設置
  • sendError(int sc):設置錯誤的狀態碼
  • sendError(int sc, String sm):設置錯誤的狀態碼,包含錯誤信息

響應頭tomcat

key:value服務器

  • setHeader(String name, String value):設置一個鍵值對,值爲string
  • setDateHeader(String name, long date):設置一個鍵值對,值爲long,long經常使用於毫秒的表示
  • setIntHeader(String name, int value):設置一個鍵值對,值爲int類型
  • setHeader(String name, String value):添加一個鍵值對,值爲string
  • setDateHeader(String name, long date):添加一個鍵值對,值爲long,long經常使用於毫秒的表示
  • setIntHeader(String name, int value):添加一個鍵值對,值爲int類型
  • add 和 set 區別在於,前置直接添加(key是能夠重複的),後者會修改原來的,沒有才會添加。

幾個常見的響應頭:jsp

  • ContentType:text/html;charset=utf-8
  • Refresh:3;url=http://path 3秒後跳轉網頁

html中meta標籤的做用就是用於向響應頭中添加信息。post

響應空行編碼

一個分隔符

響應正文

須要發送的資源

  • response.getWriter():獲取字符流
  • 父類方法getOutputSteam():獲取輸出字節流

實現請求重定向

手動實現:

實現重定向很簡單,只須要兩個步驟:

  1. 在響應頭中添加302狀態碼,告訴瀏覽器須要進行重定向
    response.setStatus(302)

  2. 在響應頭中添加Location,指定重定向的位置
    response.setHeader("Location", "http://www.baidu.com");

當用戶請求servlet時,服務器返回一個相似上面的響應頭,上面的信息告訴瀏覽器,應該從新進行一次請求,請求的地址爲 Header中的Location地址。
因此,請求重定向其實是兩次請求。

直接實現:

咱們只須要使用:response.setRedirect("http://www.baidu.com")便可實現。

經過訪問Servlet向瀏覽器傳遞一個圖片

// 獲取圖片輸入流 InputStream is = getServletContext().getResourceAsStream("/WEB-INFO/mm.jpg"); // 獲取瀏覽器的輸出流 byte[] buffer = new byte[1024]; // 將圖片篇輸入流寫出到瀏覽器中 int len = -1; while((len = is.readBuffer(buffer)) != -1){ os.write(buffer, 0, len); os.flush(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

經過訪問Servlet下載文件

相似於圖片,可是瀏覽器不能識別文件的名稱和文件的類型,須要咱們在響應頭中設置文件的類型:

ServletContext sc = getServletContext();
String mimeType = sc.getMimeType("下載的文件名稱"); // 傳入下載的文件名稱,會根據名稱的拓展名識別mime類型 response.setContentType(type);
  • 1
  • 2
  • 3

便可。

經過request對象獲取http請求協議中的內容

用來生成http請求信息。

請求首行

請求方式 請求路徑 協議/版本號

  • request.getMethod() 請求方式
  • request.getContextPath()getServletPath()…獲取請求路徑
  • 父類方法 request.getScheme() 獲取請求協議

請求頭

鍵值對

  • request.getHeader(String name)
  • request.getIntHeader(String name)
  • request.getDateHeader(String name)
  • request.getHeaderNames()
  • request.getHeaders(Sring name)一個key對應多個value

請求空行

請求正文(post纔有)

可是如下方法,不管是get仍是post請求均可以得到參數值

  • 父類方法 String getParameter(String name)
  • Map<String, String[]> getParameterMap()
  • Enumeration getParameterNames()
  • String[] getParameterValues(String name)

解決響應和請求的亂碼問題

處理get請求編碼問題

解決方案:在conf/server.xml中URIEncoding="UTF-8" 69行,

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8888" protocol="HTTP/1.1" redirectPort="8443"/>
  • 1
  • 2
  • 3
  • 4
  • 5

設置URIEncoding爲UTF-8

處理post請求編碼問題

服務器響應時的數據,即服務器向瀏覽器傳遞的數據的編碼格式由服務器決定:
編碼時使用的編碼表,使用getByte("編碼表")設置,或者使用response.setCharacterEncoding(編碼表)設置。二者的區別在於 ,前者設置字節流碼錶,後者設置字符流碼錶。

解碼時使用的編碼表,使response.setHeader("ContentType","text/html;charset=utf-8")指定http響應頭來設置。

這裏寫圖片描述


客戶端發送請求時的亂碼解決:
GET提交,參數在URL中,設置URL的解碼配置,服務器默認使用IOS-8855-1拉丁碼錶解碼URL,咱們能夠經過 tomcat/config/server.xml配置文件中:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
  • 1
  • 2
  • 3
  • 4
  • 5

添加屬性URIEncoding="UTF-8"便可將服務器默認的解碼url的方式設置爲utf-8

或者在doget方法中

將接收的亂碼文字使用新的碼錶轉換:

String name = request.getParamter("name"); // 獲取亂碼文字 byte[] bs = name.getBytes("IOS-8859-1"); // 根據亂碼碼錶,將文字轉換爲字節數組 String s = new String(bs, "UTF-8"); // 將字節數組按照新的碼錶解碼,生成文字
  • 1
  • 2
  • 3

這裏寫圖片描述

POST提交

與GET提交解碼的區別:
解碼事件不一樣,GET由於參數在URL中,因此服務器一旦接受請求就會馬上解碼參數,而POST在Servlet調用獲取參數的方法時纔會解碼。
因此,解決post請求的亂碼很簡單,只須要在參數調用前使用

request.setCharacterEncoding("utf-8");
  • 1

設置請求解碼錶便可。

request 請求轉發實現和request域

這裏寫圖片描述

這就是請求轉發,瀏覽器發送請求,servlet處理request和response部分業務,可是沒法所有處理,也沒法簡單的顯示到頁面中,因此將處理過得request和response發送給jsp,jsp進行一些業務操做,並響應給瀏覽器,展現。

請求轉發主要用來分工操做。

AServlet doGet():

// ***** 不標準自定義轉發 //todo AServlet進行業務處理,好比從數據庫獲取數據 // 處理結束後:=> // 發送給Bservlet BServlet bServlet = new BServlet(); bServlet.doGet(request, response); //*****標準轉發 // 使用request域(一個請求內有效,主要用於請求轉發) 保存數據庫的信息,發送給BServlet,即 AServlet和BServlet使用request域共享數據,request域是request對象中的一個Map。 request.setAttribute("name","Feathers"); // 向request域中存入一個鍵值對 request.getRequestDispatcher("/servlet/BServlet").forword(request.response);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

BServlet doGet():

// todo 負責輸出顯示 // 從request域中取出值 System.out.println((String)request.getAttribute("name"));
  • 1
  • 2
  • 3

注意:

不能在轉發的Servlet中向瀏覽器輸出任何響應正文的內容,可是能夠添加響應頭。
由於Servlet中,即便你添加了響應體,也會被清空。

重定向和轉發的區別

  • 重定向是一次請求,轉發一次請求
  • 重定向能夠訪問項目以外的地址,而轉發不能。
  • 重定向不能夠使用request域,而轉使用request域,一次請求,一個request對象
  • 重定向地址欄可能會發生會發生變化,而轉發必定不會
  • 重定向請求方式有可能發生改變(重定後的請求必定是get請求,只有顯示設置post纔是post請求,不然是get請求),而轉發不會
  • 重定向時response的方法(經過修改response頭來完成重定向),而請求轉發是resquest的方法(一次請求,轉發給不一樣的Servlet)

請求包含

請求轉發,轉發的Servlet不能修改請求體,而請求包含中,同請求轉發相似,可是能夠修改請求體。
用途:用來解決重複操做。
將重複的操做提取到這個Servlet中,統一進行處理。

這裏寫圖片描述

每每在多個JSP中使用,一個jsp用於處理相同的操做,其他的jsp根據是否須要處理,進行依次處理。

實現:
AServlet doGet():

response.setContentType("text/html;charset=utf-8"); // 包含 request.getRequestDispatcher("/servlet/BServlet").include(request,response); response.getWriter().write("Aservlet 處理");
  • 1
  • 2
  • 3
  • 4

BServlet doGet():

response.getWriter().write("Bservlet 處理");
  • 1

結果:

Aservlet 處理Bservlet 處理
相關文章
相關標籤/搜索