深入學習請求響應(一)---response的應用
概述
Web伺服器收到客戶端的http請求,會針對每一次請求,分別建立一個用於代表請求的request物件和代表響應的response物件。
request和response物件即然代表請求和響應,那我們要獲取客戶機提交過來的資料,只需要找request物件就行了;要向客戶機輸出資料,只需要找response物件就行了。
response的繼承結構
ServletResponse -- 通用的response。提供了一個響應應該具有最基本的屬性和方法。 |-HttpServletResponse -- 在ServletResponse的基礎上針對於HTTP協議增加了很多強化的屬性和方法。
利用response向瀏覽器輸出一段資料
package me.zipstream.response;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setContentType("text/html;charset=utf-8");//通知瀏覽器用u8來解碼
// response.getOutputStream().write("中國".getBytes("utf-8"));
response.setCharacterEncoding("utf-8" );//通知伺服器以u8來編碼。
//其實上面這句話可以省略,因為只要有下面這句話,伺服器就會預設使用u8來編碼。
response.setContentType("text/html; charset=utf-8");//通知瀏覽器以u8來解碼。
response.getWriter().write("中國");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
另外,這裡需要注意的是:
對於一次請求,Response的getOutputStream()方法和getWriter()方法互斥,只能呼叫其一,特別注意forward後(在請求轉發時)也不要違反這一規則。
利用response實現下載
package me.zipstream.response;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode("機械鍵盤.jpg", "utf-8"));
InputStream in = new FileInputStream(this.getServletContext().getRealPath("1.jpg"));
OutputStream out = response.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len=in.read(buf))!=-1){
out.write(buf, 0, len);
}
in.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/*
* URL編碼與解碼的過程
*/
/*
public static void main(String[] args) throws Exception {
String str = "文明開化";
String str2 = URLEncoder.encode(str, "utf-8");
System.out.println(str2);
String str3 = URLDecoder.decode("%E6%96%87%E6%98%8E%E5%BC%80%E5%8C%96", "utf-8");
System.out.println(str3);
}
*/
}
設定響應頭content-disposition為“attachment;filename=xxx.xxx”。
利用輸入流將檔案讀取進來,再利用Response獲取響應流輸出。
如果檔名為中文,一定要進行URL編碼,編碼所用的碼錶必須是utf-8。
注意:
service方法返回後,伺服器會自己檢查Response獲取的OutputStream()或者Writer()是否關閉,如果沒有關閉,伺服器自動幫你關閉,一般情況下不要自己關閉這兩個流。
利用response實現定時重新整理頁面
package me.zipstream.response;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RefreshServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//隔1s重新整理一次本頁
// response.getWriter().write(new Date().toLocaleString());
// response.setHeader("Refresh", "1");
//隔3s跳轉到主頁
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("恭喜您註冊成功,3秒後回到主頁...");
response.setHeader("Refresh", "3;url=/Day04/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
設定響應頭Refresh為一個數值,指定多少秒後重新整理當前頁面。
設定響應頭Refresh為 3;url=/Day05/index.jsp
,指定多少秒後重新整理到哪個頁面。
可以用來實現註冊後“註冊成功,3秒後跳轉到主頁”的功能。
另外,在HTML可以利用<meta http-equiv= "" content="">
標籤模擬響應頭的功能。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Refresh" content="3;url=/Day04/index.jsp">
</head>
<body>
恭喜您註冊成功,3秒後回到主頁.... <br>
</body>
</html>
利用response控制是否快取資源
不快取資源:
控制瀏覽器不要快取(如驗證碼圖片不快取),設定expires為0或-1,設定Cache-Control為no-cache,Pragma為no-cache
package me.zipstream.response;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class NoCacheServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setIntHeader("Expires", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("當前時間是: " + new Date().toLocaleString());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
快取資源:
即使不明確指定瀏覽器也會快取資源,這種快取沒有截至日期。當在位址列重新輸入地址時會用快取,但是當重新整理或重新開瀏覽器訪問時會重新獲得資源。
如果明確指定快取時間,瀏覽器快取時會有一個截至日期,在截至日期到期之前,當在位址列重新輸入地址或重新開瀏覽器訪問時都會用快取,而當重新整理時會重新獲得資源。
package me.zipstream.response;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CacheServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setDateHeader("Expires", System.currentTimeMillis() + 1000l*3600*24*30);
//注意這裡時間的設定。後面不要都是int型的,至少有一個為long型。
InputStream in = new FileInputStream(this.getServletContext().getRealPath("1.jpg"));
OutputStream out = response.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len=in.read(buf)) != -1){
out.write(buf, 0, len);
}
in.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
利用response實現請求重定向
package me.zipstream.response;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RedirectServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setStatus(302);
// response.setHeader("Location", "/Day04/index.jsp");
response.sendRedirect("/Day04/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
古老方法:
response.setStatus(302);
response.addHeader("Location","URL");
快捷方式:
response.sendRedirect("URL");