Servlet 請求(第三篇)

往前的娘娘發表於2021-01-01

request物件包含所有客戶的資訊,在HTTP協議中,這些資訊 是通過header和body傳遞到服務端

3.1、HTTP 協議引數

  • 請求引數是通過字串傳送伺服器的

  • 請求引數是key-value的模式

  • 下列方法可獲取引數

    • getParameter 獲取第一個引數
    • getParameterNames 獲取所有引數的名稱
    • getParameterValues 獲取所有引數的值
    • getParameterMap 獲取key-value的map
  • 例子

    • 比如一個查詢條件是 a=hello , 一個post的body入參 a=goodbye&a=world
      那麼結果引數: a=(hello, goodbye, world)
      
  • path引數只是GET請求獨有特性(在HTTP1.1), 他必須通過getRequestURI方法或getPathInfo方法

3.1.1、當引數是可獲取的時候

  • post 表單提交必須滿足如下要求
    1. 請求是一個HTTP或HTTPS請求
    2. HTTP的方式是POST
    3. 內容格式 application/x-www-form-urlencoded
    4. servlet 對應任何getParameter做引數初始化處理
  • 如果不滿足上面的要求,那麼獲取引數只能通過inputStream獲取,滿足就不能通過inputStream獲取

3.2、檔案上傳

  • servlet容器允許檔案上傳的,內容格式是multipart/form-data

  • 以下任意一個條件被滿足,servlet容器按照multipart/form-data格式處理

    • 請求被標記@MultipartConfig
    • 部署描述符包含multipart-config元素去處理這個請求
  • servlet容器提供multipart/form-data處理功能,那麼資料可以通過哪些HttpServletRequest方法獲得

    • public Collection getParts()

    • public Part getPart(String name )

    • 每個Part都可以獲取頭部資訊、內容資訊,以及檔案本身的資訊,通過方法Part.getInputStream方法

  • 如果servlet容器並不提供multi-part/form-data處理,那麼檔案資料可以通過HttpServletRequest.getInputStream

3.3、屬性

  • 屬性對引數一種補充
  • 屬性servlet之間傳遞資訊(通過RequestDispatcher)
  • 獲取和設定屬性的介面和方法如下ServletRequest
    • getAttribute
    • getAttributeNames
    • setAttribute
  • 還一點與引數不同地方,屬性值只能與一個屬性名關聯。
  • 在屬性key命名時候,推薦遵循java包命名方法,不用使用java或oracle,sun開頭保留

3.4、請求頭

  • 獲取請求頭方法(HttpServletRequest)
    • getHeader
    • getHeaders
    • getHeaderNames
  • 一個header的name 可以對應多個值, 如果獲取第一個header值可通過getHeader方法獲取,如果獲得所有的值可以通過getHeaders,
  • header還提供一些格式轉換的方法
    • getIntHeader 將獲取字串轉換成int型別 (轉換不成功將會丟擲 NumberFormatException)
    • getDateHeader 將獲取字串轉換成date型別(轉換不成功,將會丟擲IllegalArgumentException)

3.5、請求路徑引數

  • Request URI路徑

    • Context Path (上下文路徑) 以/開頭
    • Servlet Path (Servlet路徑) mapping確定的部分
    • PathInfo 資訊 不能確定的uri部分 ,可以是null
  • 獲取這些資訊可以通過如下方法獲取

    • getContextPath
    • getServletPath
    • getPathInfo
  • 總體來說 requestURI = contextPath + servletPath + pathInfo

  • 配置

  • Context Path/catalog
    Servlet MappingPattern: /lawn/*處理uri萬用字元
    Servlet: LawnServlet處理Servlet
    Servlet MappingPattern: /garden/*
    Servlet: GardenServlet
    Servlet MappingPattern: *.jsp
    Servlet: JSPServlet

    例子

  • Request Path(請求路徑)Path Elements(路徑元素)
    /catalog/lawn/index.htmlContextPath: /catalog
    ServletPath: /lawn
    PathInfo: /index.html
    /catalog/garden/implementsContextPath: /catalog
    ServletPath: /garden
    PathInfo: /implements
    /catalog/help/feedback.jspContextPath: /catalog
    ServletPath: /help/feedback.jsp
    PathInfo: null

3.6、路徑轉換方法

  • 獲取特定位置路徑位置
    • ServletContext.getRealPath 真實檔案路徑(本地檔案系統)也有可能返回null
    • HttpServletRequest.getPathTranslated 獲取真實檔案路徑的pathInfo資訊

3.7、非阻塞IO

  • 非同步請求提高服務擴充套件能力,那麼什麼時候可以獲取到結果,所有需要註冊回撥或監聽器
  • ReadListener ( 讀取監聽器)
    • onDataAvailable() 資料讀取準備好(ServletInputStream), 容器會呼叫這個方法
    • onAllDataRead() 資料讀取完畢, (ServletRequest)
    • onError(Throwable t) 處理過程發生異常,都會呼叫這個方法
  • 除了ReadListener, 還有一些相關的方法新增到ServletInputStream
    • boolean isFinished() ServletInputStream 的請求資料被讀取完成
    • boolean isReady() 資料是否準備好
    • void setReadListener(ReadListener listener) 只能非同步使用,其它同步使用丟擲IllegalStateException

3.8、Cookies

  • 客戶端快取資料,key-value
  • HttpOnly 標識cookies 暗示不希望暴露到客戶端指令碼使用,減少跨域攻擊

3.9、SSL屬性

  • 支援安全屬性傳輸,必須暴露如下引數給servlet

  • 屬性屬性名稱java型別
    cipher suitejavax.servlet.request.cipher_suiteString
    bit size of the algorithmjavax.servlet.request.key_sizeInteger
    SSL session idjavax.servlet.request.ssl_session_idString

    如果是證照驗證的,需要屬性 java.security.cert.X509Certificate

3.10、國際化

  • 使用 Accept-Language 客戶接受語言
  • ServletRequest介面
    • getLocale
    • getLocales

##3.11、請求資料編碼

  • 預設資料編碼 是 ISO-8859-1
  • 如果沒有設定資料編碼,那麼呼叫getCharacterEncoding方法返回null
  • 當然在解析資料之前需要呼叫setCharacterEncoding(String enc)

3.12、Request的生命週期

  • 請求物件在servlet服務期間不會被回收,比如service和doFilter(過濾)方法,如果非同步的話會呼叫startAsync 到 complete 完成整個過程,除此之外不要在非request的scope(域)內呼叫startAsync,可以引起不確定結果

相關文章