日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HttpServletRequest 对象

發布時間:2023/12/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HttpServletRequest 对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

HttpServletRequest 對象

HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中,通過這個對象提供的方法,可以獲得客戶端請求的所有信息。

其他的具體方法就不詳細描述了,具體方法上的使用看API,或者網上查查,有很多的。這里就介紹一下 請求方式 和 獲取參數 的問題


請求方式

根據HTTP標準,HTTP請求可以使用多種請求方法。

HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法



其實真正有多少請求方式我具體也沒有詳細了解過。我在這里就詳細介紹一下經常的能接觸到的請求.

GET:從服務器取出資源

POST:在服務器新建一個資源

PUT:在服務器更新資源(客戶端提供改變后的完整資源)

PACTH:在服務器更新資源(客戶端提供改變的屬性)

DELETE:從服務器刪除資源

OPTIONS:獲取信息,關于資源的哪些屬性是客戶端可以改變的


這些接口在遇到服務端是以RESTful風格命名參數的時候是很有用的。這點其實可以參考阮一峰大神的《RESTful API 設計指南》,老實說這里大部分東西也是從那里剽竊來的,有些也加入自己的思考理解,也不知道對不對,說回來,讀書人的這種事情能叫做抄嗎(原諒我的無恥)。


其他的接口請求都是很好理解的,這里介紹一下OPTIONS,平常好像真的沒怎么遇到過這個請求,理解上“獲取信息”的請求,有些不知所謂。
其實不是的,遇到最多的請求其實是跨域的情況,在跨域的情況下,瀏覽器在第一次發送請求之前,會發送一個OPTIONS的請求方式的請求。(當然這里指的是非簡單請求)。我們稱之為“預檢請求”,好了我又想抄了《跨域資源共享 CORS 詳解》,阮一峰大神出品(感覺我像死忠粉一樣)。

雖然瀏覽器做了預檢請求,但是這時候需要服務端的配合

public class SimpleCORSFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException{HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Cache-Control, token");chain.doFilter(req, res);}@Overridepublic void destroy(){// TODO Auto-generated method stub}@Overridepublic void init(FilterConfig arg0) throws ServletException{// TODO Auto-generated method stub}}

需要追加一個這樣的過濾器,具體xml配置自行解決吧。

參數解釋:

Access-Control-Allow-Origin:

這個Header是用來告訴瀏覽器,我的這個URL的資源是允許任何來源的請求訪問我,如果值是*則表示表示接受任意域名的請求。

Access-Control-Allow-Methods:

顧名思義,表明服務器支持的所有跨域請求的方法。

Access-Control-Max-Age:

用來指定本次預檢請求的有效期,單位為秒。在上面的設置中,即允許緩存該條回應為3600秒,在此期間不用發出另一條預檢請求。

Access-Control-Allow-Headers:

表明服務器支持的所有頭信息字段,不限于瀏覽器在”預檢”中請求的字段。原文:The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

這里是關于跨域請求的事情了,扯遠了。


Request請求在body體中獲取參數

在Request請求獲取參數的方式多種多樣
這里我就給幾個鏈接吧《Spring Controller 獲取請求參數的幾種方法》,《springmvc請求參數獲取的幾種方法》



這里想要說明一下request.getParameter(),request.getInputStream(),request.getReader()中request.getInputStream(),request.getReader()這兩種方式。

這兩個方法都是將request當做一個流對象來獲取數據,區別呢是getInputStream 字節流得到的對象是InputStream對象,如果里邊有二進制的話只能用這個讀,getReader 字符流得到的是Reader對象,會按照請求消息中指定的字符集編碼轉換成文本字符串。 對于對于流來說我們可以把他們理解成管道,既然是管道,那么只能讀取一次,第一次讀取的時候可以讀取到數據,但是接下來的讀取操作都讀取不到數據。

原因:

1 . 一個InputStream對象在被讀取完成后,將無法被再次讀取,始終返回-1; 2 . InputStream并沒有實現reset方法(可以重置首次讀取的位置),無法實現重置操作;


解決方法

1.使用request、session等來緩存讀取到的數據,這種方式很容易實現,只要setAttribute和getAttribute就行(但是這樣寫未免太不優雅了);

2.使用HttpServletRequestWrapper來包裝HttpServletRequest,在MAPIHttpServletRequestWrapper中初始化讀取request的InputStream數據,以byte[]形式緩存在其中,然后在Filter中將request轉換為包裝過的request(強烈推薦如下放大);代碼如下:

重寫request

public class MAPIHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; // 報文 public MAPIHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); body = StreamUtil.readBytes(request.getInputStream()); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } }; } }

配置相應過濾器

public class HttpServletRequestReplacedFilter implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest requestWrapper = null; if(request instanceof HttpServletRequest) { requestWrapper = new MAPIHttpServletRequestWrapper((HttpServletRequest) request); } if(requestWrapper == null) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } } @Override public void init(FilterConfig arg0) throws ServletException { } }

最后注意 request.getParameter()、 request.getInputStream()、request.getReader()這三種方法是有沖突的,因為流只能被讀一次。
比如:

當form表單內容采用 enctype=application/x-www-form-urlencoded編碼時,先通過調用request.getParameter() 方法得到參數后,再調用 request.getInputStream()或request.getReader()已經得不到流中的內容,因為在調用 request.getParameter()時系統可能對表單中提交的數 據以流的形式讀了一次,反之亦然。

當form表單內容采用 enctype=multipart/form-data編碼時,即使先調用request.getParameter()也得不到數據,但是這時調用 request.getParameter()方法對 request.getInputStream()或request.getReader()沒有沖突,即使已經調用了 request.getParameter()方法也 可以通過調用request.getInputStream()或request.getReader()得 到表單中的數據,而request.getInputStream()和request.getReader()在同 一個響應中是不能混合使用的,如果混合使用就會拋異常。
此處參考了

https://www.cnblogs.com/v5hanhan/p/5646054.html

https://www.cnblogs.com/fzng/p/7227787.html?utm_source=itdadao&utm_medium=referral

轉載于:https://www.cnblogs.com/liyunq/p/9724605.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的HttpServletRequest 对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。