HttpServletRequest
封装了一个HTTP请求,它实际上是从ServletRequest
继承而来。最早设计Servlet时,设计者希望Servlet不仅能处理HTTP,也能处理类似SMTP等其他协议,因此,单独抽出了ServletRequest
接口,但实际上除了HTTP外,并没有其他协议会用Servlet处理,所以这是一个过度设计。
我们通过HttpServletRequest
提供的接口方法可以拿到HTTP请求的几乎全部信息,常用的方法有:
"GET"
,"POST"
;"/hello"
;"name=Bob&a=1&b=2"
;"application/x-www-form-urlencoded"
;""
;"http"
,"https"
;此外,HttpServletRequest
还有两个方法:setAttribute()
和getAttribute()
,可以给当前HttpServletRequest
对象附加多个Key-Value,相当于把HttpServletRequest
当作一个Map<String, Object>
使用。
HttpServletResponse
封装了一个HTTP响应。由于HTTP响应必须先发送Header,再发送Body,所以,操作HttpServletResponse
对象时,必须先调用设置Header的方法,最后调用发送Body的方法。
常用的设置Header的方法有:
200
;"text/html"
;"UTF-8"
;写入响应时,需要通过getOutputStream()
获取写入流,或者通过getWriter()
获取字符流,二者只能获取其中一个。
写入响应前,无需设置setContentLength()
,因为底层服务器会根据写入的字节数自动设置,如果写入的数据量很小,实际上会先写入缓冲区,如果写入的数据量很大,服务器会自动采用Chunked编码让浏览器能识别数据结束符而不需要设置Content-Length头。
但是,写入完毕后调用flush()
却是必须的,因为大部分Web服务器都基于HTTP/1.1协议,会复用TCP连接。如果没有调用flush()
,将导致缓冲区的内容无法及时发送到客户端。此外,写入完毕后千万不要调用close()
,原因同样是因为会复用TCP连接,如果关闭写入流,将关闭TCP连接,使得Web服务器无法复用此TCP连接。
写入完毕后对输出流调用flush()而不是close()方法!