Response響應(yīng)對(duì)象主要將JSP容器處理后的結(jié)果傳回到客戶端??梢酝ㄟ^(guò)response變量設(shè)置HTTP的狀態(tài)和向客戶端發(fā)送數(shù)據(jù),如Cookie、HTTP文件頭信息等。
一個(gè)典型的響應(yīng)看起來(lái)就像下面這樣:
HTTP/1.1 200 OK
Content-Type: text/html
Header2: ...
...
HeaderN: ...
(空行)
<!doctype ...>
<html>
<head>...</head>
<body>
...
</body>
</html>
狀態(tài)行包含HTTP版本信息,比如HTTP/1.1,一個(gè)狀態(tài)碼,比如200,還有一個(gè)非常短的信息對(duì)應(yīng)著狀態(tài)碼,比如OK。
下表摘要出了HTTP1.1響應(yīng)頭中最有用的部分,在網(wǎng)絡(luò)編程中您將會(huì)經(jīng)常見(jiàn)到它們:
響應(yīng)頭 | 描述 |
---|---|
Allow | 指定服務(wù)器支持的request方法(GET,POST等等) |
Cache-Control | 指定響應(yīng)文檔能夠被安全緩存的情況。通常取值為 public,private 或no-cache 等等。 Public意味著文檔可緩存,Private意味著文檔只為單用戶服務(wù)并且只能使用私有緩存。No-cache 意味著文檔不被緩存。 |
Connection | 命令瀏覽器是否要使用持久的HTTP連接。close值 命令瀏覽器不使用持久HTTP連接,而keep-alive 意味著使用持久化連接。 |
Content-Disposition | 讓瀏覽器要求用戶將響應(yīng)以給定的名稱(chēng)存儲(chǔ)在磁盤(pán)中 |
Content-Encoding | 指定傳輸時(shí)頁(yè)面的編碼規(guī)則 |
Content-Language | 表述文檔所使用的語(yǔ)言,比如en, en-us,,ru等等 |
Content-Length | 表明響應(yīng)的字節(jié)數(shù)。只有在瀏覽器使用持久化 (keep-alive) HTTP 連接時(shí)才有用 |
Content-Type | 表明文檔使用的MIME類(lèi)型 |
Expires | 指明啥時(shí)候過(guò)期并從緩存中移除 |
Last-Modified | 指明文檔最后修改時(shí)間??蛻舳丝梢?緩存文檔并且在后續(xù)的請(qǐng)求中提供一個(gè) If-Modified-Since請(qǐng)求頭 |
Location | 在300秒內(nèi),包含所有的有一個(gè)狀態(tài)碼的響應(yīng)地址,瀏覽器會(huì)自動(dòng)重連然后檢索新文檔 |
Refresh | 指明瀏覽器每隔多久請(qǐng)求更新一次頁(yè)面。 |
Retry-After | 與503 (Service Unavailable)一起使用來(lái)告訴用戶多久后請(qǐng)求將會(huì)得到響應(yīng) |
Set-Cookie | 指明當(dāng)前頁(yè)面對(duì)應(yīng)的cookie |
HttpServletResponse類(lèi)
response 對(duì)象是 javax.servlet.http.HttpServletResponse 類(lèi)的一個(gè)實(shí)例。就像服務(wù)器會(huì)創(chuàng)建request對(duì)象一樣,它也會(huì)創(chuàng)建一個(gè)客戶端響應(yīng)。
response對(duì)象定義了處理創(chuàng)建HTTP信息頭的接口。通過(guò)使用這個(gè)對(duì)象,開(kāi)發(fā)者們可以添加新的cookie或時(shí)間戳,還有HTTP狀態(tài)碼等等。
下表列出了用來(lái)設(shè)置HTTP響應(yīng)頭的方法,這些方法由HttpServletResponse 類(lèi)提供:
S.N. | 方法 & 描述 |
---|---|
1 | String encodeRedirectURL(String url)對(duì)sendRedirect()方法使用的URL進(jìn)行編碼 |
2 | String encodeURL(String url)將URL編碼,回傳包含Session ID的URL |
3 | boolean containsHeader(String name)返回指定的響應(yīng)頭是否存在 |
4 | boolean isCommitted()返回響應(yīng)是否已經(jīng)提交到客戶端 |
5 | void addCookie(Cookie cookie)添加指定的cookie至響應(yīng)中 |
6 | void addDateHeader(String name, long date)添加指定名稱(chēng)的響應(yīng)頭和日期值 |
7 | void addHeader(String name, String value)添加指定名稱(chēng)的響應(yīng)頭和值 |
8 | void addIntHeader(String name, int value)添加指定名稱(chēng)的響應(yīng)頭和int值 |
9 | void flushBuffer()將任何緩存中的內(nèi)容寫(xiě)入客戶端 |
10 | void reset()清除任何緩存中的任何數(shù)據(jù),包括狀態(tài)碼和各種響應(yīng)頭 |
11 | void resetBuffer()清除基本的緩存數(shù)據(jù),不包括響應(yīng)頭和狀態(tài)碼 |
12 | void sendError(int sc)使用指定的狀態(tài)碼向客戶端發(fā)送一個(gè)出錯(cuò)響應(yīng),然后清除緩存 |
13 | void sendError(int sc, String msg)使用指定的狀態(tài)碼和消息向客戶端發(fā)送一個(gè)出錯(cuò)響應(yīng) |
14 | void sendRedirect(String location)使用指定的URL向客戶端發(fā)送一個(gè)臨時(shí)的間接響應(yīng) |
15 | void setBufferSize(int size)設(shè)置響應(yīng)體的緩存區(qū)大小 |
16 | void setCharacterEncoding(String charset)指定響應(yīng)的編碼集(MIME字符集),例如UTF-8 |
17 | void setContentLength(int len)指定HTTP servlets中響應(yīng)的內(nèi)容的長(zhǎng)度,此方法用來(lái)設(shè)置 HTTP Content-Length 信息頭 |
18 | void setContentType(String type)設(shè)置響應(yīng)的內(nèi)容的類(lèi)型,如果響應(yīng)還未被提交的話 |
19 | void setDateHeader(String name, long date)使用指定名稱(chēng)和值設(shè)置響應(yīng)頭的名稱(chēng)和內(nèi)容 |
20 | void setHeader(String name, String value)使用指定名稱(chēng)和值設(shè)置響應(yīng)頭的名稱(chēng)和內(nèi)容 |
21 | void setIntHeader(String name, int value)使用指定名稱(chēng)和值設(shè)置響應(yīng)頭的名稱(chēng)和內(nèi)容 |
22 | void setLocale(Locale loc)設(shè)置響應(yīng)的語(yǔ)言環(huán)境,如果響應(yīng)尚未被提交的話 |
23 | void setStatus(int sc)設(shè)置響應(yīng)的狀態(tài)碼 |
HTTP響應(yīng)頭程序示例
接下來(lái)的例子使用setIntHeader()方法和setRefreshHeader()方法來(lái)模擬一個(gè)數(shù)字時(shí)鐘:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥(niǎo)教程(runoob.com)</title>
</head>
<body>
<h2>自動(dòng)刷新實(shí)例</h2>
<%
// 設(shè)置每隔5秒自動(dòng)刷新
response.setIntHeader("Refresh", 5);
// 獲取當(dāng)前時(shí)間
Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
if(calendar.get(Calendar.AM_PM) == 0)
am_pm = "AM";
else
am_pm = "PM";
String CT = hour+":"+ minute +":"+ second +" "+ am_pm;
out.println("當(dāng)前時(shí)間: " + CT + "\n");
%>
</body>
</html>
將以上代碼保存為main.jsp,然后通過(guò)瀏覽器訪問(wèn)它。它將會(huì)每隔5秒顯示一下系統(tǒng)當(dāng)前時(shí)間。
我們可以看下以下 Gif 演示圖:
您也可以自己動(dòng)手修改以上代碼,試試使用其他的方法,將能得到更深的體會(huì)。
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
SP的工作模式是請(qǐng)求/響應(yīng)模式,客戶端首先發(fā)出HTTP請(qǐng)求,JSP程序收到請(qǐng)求后將進(jìn)行處理并返回處理結(jié)果。在一個(gè)JSP文件第一次被請(qǐng)求的時(shí)候,JSP引擎(容器)把該JSP文件轉(zhuǎn)換成一個(gè)Servlet,而這個(gè)引擎本身也是一個(gè)Servlet。JSP的運(yùn)行原理如圖11-4所示。
圖11-4 JSP的運(yùn)行原理
JSP的運(yùn)行過(guò)程具體如下。
(1)客戶端發(fā)出請(qǐng)求,請(qǐng)求訪問(wèn)JSP文件。
(2)JSP容器先將JSP文件轉(zhuǎn)換成一個(gè)Java源文件(Java Servlet源程序),在轉(zhuǎn)換過(guò)程中,如果發(fā)現(xiàn)JSP文件中存在任何語(yǔ)法錯(cuò)誤,則中斷轉(zhuǎn)換過(guò)程,并向服務(wù)端和客戶端返回出錯(cuò)信息。
(3)如果轉(zhuǎn)換成功,則JSP容器會(huì)將生成的Java源文件編譯成相應(yīng)的字節(jié)碼文件*.class。該class文件就是一個(gè)Servlet,Servlet容器會(huì)像處理其他Servlet一樣處理它。
(4)由Servlet容器加載轉(zhuǎn)換后的Servlet類(lèi)(class文件)創(chuàng)建一個(gè)該Servlet(JSP頁(yè)面的轉(zhuǎn)換結(jié)果)的實(shí)例,并執(zhí)行Servlet的jspInit()方法。jsInit()方法在Servlet的整個(gè)生命周期中只會(huì)執(zhí)行一次。
(5)執(zhí)行jspService()方法處理客戶端的請(qǐng)求。對(duì)于每一個(gè)請(qǐng)求,JSP容器都會(huì)創(chuàng)建一個(gè)新的線程處理它。如果多個(gè)客戶端同時(shí)請(qǐng)求該JSP文件,則JSP容器會(huì)創(chuàng)建多個(gè)線程,使每一個(gè)客戶端請(qǐng)求都對(duì)應(yīng)一個(gè)線程。
(6)如果JSP文件被修改了,則服務(wù)器將根據(jù)設(shè)置決定是否對(duì)該文件重新進(jìn)行編譯,如果需要重新編譯,則使用重新編譯后的結(jié)果取代內(nèi)存中的Servlet,并繼續(xù)上述處理過(guò)程。需要注意的是,雖然JSP效率很高,但在第一次調(diào)用時(shí)往往由于需要轉(zhuǎn)換和編譯,所以會(huì)產(chǎn)生一些輕微的延遲。
(7)如果系統(tǒng)出現(xiàn)資源不足等問(wèn)題,JSP容器可能會(huì)以某種不確定的方式將Servlet從內(nèi)存中移除,發(fā)生這種情況的時(shí)候,首先會(huì)調(diào)用jspDestroy()方法,然后Servlet實(shí)例會(huì)被作為“垃圾”進(jìn)行處理。
(8)當(dāng)請(qǐng)求處理完成后,響應(yīng)對(duì)象由JSP容器接收,并將HTML格式的響應(yīng)信息發(fā)送回客戶端。
Controller和@RestController有啥區(qū)別呢,
面試題看到有這么一題
以前沒(méi)注意今天特意查了下
@RestController注解,相當(dāng)于@Controller+@ResponseBody兩個(gè)注解的結(jié)合,返回json數(shù)據(jù)不需要在方法前面加@ResponseBody注解了,但使用@RestController這個(gè)注解,就不能返回jsp,html頁(yè)面,視圖解析器無(wú)法解析jsp,html頁(yè)面
相當(dāng)于以前的寫(xiě)法
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。