HttpServletRequest 对象
HttpServletRequest 對象
HttpServletRequest對象代表客戶端的請求,當(dāng)客戶端通過HTTP協(xié)議訪問服務(wù)器時,HTTP請求頭中的所有信息都封裝在這個對象中,通過這個對象提供的方法,可以獲得客戶端請求的所有信息。
其他的具體方法就不詳細(xì)描述了,具體方法上的使用看API,或者網(wǎng)上查查,有很多的。這里就介紹一下 請求方式 和 獲取參數(shù) 的問題
請求方式
根據(jù)HTTP標(biāo)準(zhǔn),HTTP請求可以使用多種請求方法。
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法
其實真正有多少請求方式我具體也沒有詳細(xì)了解過。我在這里就詳細(xì)介紹一下經(jīng)常的能接觸到的請求.
GET:從服務(wù)器取出資源
POST:在服務(wù)器新建一個資源
PUT:在服務(wù)器更新資源(客戶端提供改變后的完整資源)
PACTH:在服務(wù)器更新資源(客戶端提供改變的屬性)
DELETE:從服務(wù)器刪除資源
OPTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶端可以改變的
這些接口在遇到服務(wù)端是以RESTful風(fēng)格命名參數(shù)的時候是很有用的。這點其實可以參考阮一峰大神的《RESTful API 設(shè)計指南》,老實說這里大部分東西也是從那里剽竊來的,有些也加入自己的思考理解,也不知道對不對,說回來,讀書人的這種事情能叫做抄嗎(原諒我的無恥)。
其他的接口請求都是很好理解的,這里介紹一下OPTIONS,平常好像真的沒怎么遇到過這個請求,理解上“獲取信息”的請求,有些不知所謂。
其實不是的,遇到最多的請求其實是跨域的情況,在跨域的情況下,瀏覽器在第一次發(fā)送請求之前,會發(fā)送一個OPTIONS的請求方式的請求。(當(dāng)然這里指的是非簡單請求)。我們稱之為“預(yù)檢請求”,好了我又想抄了《跨域資源共享 CORS 詳解》,阮一峰大神出品(感覺我像死忠粉一樣)。
雖然瀏覽器做了預(yù)檢請求,但是這時候需要服務(wù)端的配合
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配置自行解決吧。
參數(shù)解釋:
Access-Control-Allow-Origin:
這個Header是用來告訴瀏覽器,我的這個URL的資源是允許任何來源的請求訪問我,如果值是*則表示表示接受任意域名的請求。
Access-Control-Allow-Methods:
顧名思義,表明服務(wù)器支持的所有跨域請求的方法。
Access-Control-Max-Age:
用來指定本次預(yù)檢請求的有效期,單位為秒。在上面的設(shè)置中,即允許緩存該條回應(yīng)為3600秒,在此期間不用發(fā)出另一條預(yù)檢請求。
Access-Control-Allow-Headers:
表明服務(wù)器支持的所有頭信息字段,不限于瀏覽器在”預(yù)檢”中請求的字段。原文: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.
這里是關(guān)于跨域請求的事情了,扯遠(yuǎn)了。
Request請求在body體中獲取參數(shù)
在Request請求獲取參數(shù)的方式多種多樣
這里我就給幾個鏈接吧《Spring Controller 獲取請求參數(shù)的幾種方法》,《springmvc請求參數(shù)獲取的幾種方法》
這里想要說明一下request.getParameter(),request.getInputStream(),request.getReader()中request.getInputStream(),request.getReader()這兩種方式。
這兩個方法都是將request當(dāng)做一個流對象來獲取數(shù)據(jù),區(qū)別呢是getInputStream 字節(jié)流得到的對象是InputStream對象,如果里邊有二進(jìn)制的話只能用這個讀,getReader 字符流得到的是Reader對象,會按照請求消息中指定的字符集編碼轉(zhuǎn)換成文本字符串。 對于對于流來說我們可以把他們理解成管道,既然是管道,那么只能讀取一次,第一次讀取的時候可以讀取到數(shù)據(jù),但是接下來的讀取操作都讀取不到數(shù)據(jù)。
原因:
1 . 一個InputStream對象在被讀取完成后,將無法被再次讀取,始終返回-1; 2 . InputStream并沒有實現(xiàn)reset方法(可以重置首次讀取的位置),無法實現(xiàn)重置操作;解決方法
1.使用request、session等來緩存讀取到的數(shù)據(jù),這種方式很容易實現(xiàn),只要setAttribute和getAttribute就行(但是這樣寫未免太不優(yōu)雅了);
2.使用HttpServletRequestWrapper來包裝HttpServletRequest,在MAPIHttpServletRequestWrapper中初始化讀取request的InputStream數(shù)據(jù),以byte[]形式緩存在其中,然后在Filter中將request轉(zhuǎn)換為包裝過的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(); } }; } }配置相應(yīng)過濾器
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()這三種方法是有沖突的,因為流只能被讀一次。
比如:
當(dāng)form表單內(nèi)容采用 enctype=application/x-www-form-urlencoded編碼時,先通過調(diào)用request.getParameter() 方法得到參數(shù)后,再調(diào)用 request.getInputStream()或request.getReader()已經(jīng)得不到流中的內(nèi)容,因為在調(diào)用 request.getParameter()時系統(tǒng)可能對表單中提交的數(shù) 據(jù)以流的形式讀了一次,反之亦然。
當(dāng)form表單內(nèi)容采用 enctype=multipart/form-data編碼時,即使先調(diào)用request.getParameter()也得不到數(shù)據(jù),但是這時調(diào)用 request.getParameter()方法對 request.getInputStream()或request.getReader()沒有沖突,即使已經(jīng)調(diào)用了 request.getParameter()方法也 可以通過調(diào)用request.getInputStream()或request.getReader()得 到表單中的數(shù)據(jù),而request.getInputStream()和request.getReader()在同 一個響應(yīng)中是不能混合使用的,如果混合使用就會拋異常。
此處參考了
https://www.cnblogs.com/v5hanhan/p/5646054.html
https://www.cnblogs.com/fzng/p/7227787.html?utm_source=itdadao&utm_medium=referral
轉(zhuǎn)載于:https://www.cnblogs.com/liyunq/p/9724605.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的HttpServletRequest 对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MAC快捷键对照表
- 下一篇: Redis工具之Jedis