Response
1、Response的運行過程
客戶端發送請求(http請求)---->Tomcat引擎(解析,內部封裝request信息以及response空對象)------>對應的Web程序的Servlet-------->而後將Response響應放到response緩衝區(相似)------->Tomcat引擎取出Response緩衝區內容------>Tomcat引擎將Response緩衝區內容與引擎本身添加的信息組裝成一個http響應發送給客戶端
http響應(三部分):
http響應行
http響應頭
http響應體
一、經過Response設置響應行
設置響應行的狀態碼
setStatus( int sc )
//手動設置http響應行中的狀態碼
response.setStatus(302);
二、經過Response設置響應頭
addHeader(String name, String value)
addIntHeader(String name, int value)
addDateHeader(String name, long date)
Date date = new Date();
//設置響應頭
response.addHeader("name", "zhangsan");
response.addIntHeader("age", 28);
response.addDateHeader("birthday", date.getTime());
setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)
其中,add表示添加(同名,會添加多個),而set表示設置(同名的,後面的會覆蓋前面的)。
注:本身經過抓包查看響應信息。
三、重定向
什麼是重定向?
客戶端找servlet1要資源,servlet1沒有資源,但知道servlet2有資源,而後告訴客戶端,客戶端去找servlet2要資源的過程就叫重定向。
俗話理解:你找張三借錢,張三沒錢,但知道李四有錢,而後告訴你李四有錢,讓你去找李四借錢。
特定:a、訪問服務器兩次或屢次。b、地址欄的地址發生變化(自動變化)
怎樣設定重定向?
狀態碼:302 響應頭:location (表明重定向的地址)
//沒有響應,告知客戶端去重定向到Servlet2
//1.設置狀態碼302
response.setStatus(302);
//2.設置響應頭location
response.setHeader("Location", "/WEB14_Response/servlet2");
//JavaEE已經封裝了一個重定向的方法sendRedirect(url)
response.sendRedirect("/WEB14_Response/servlet2");
替代上面代碼。
設置定時刷新,也可以達到重定向的功能!
四、經過Response設置響應體
a、響應體設置文本
PrintWriter writer = response.getWriter();
writer.write("hello China");
writer.write("中國!!!");
中文亂碼問題?
通知Response查詢UTF-8的碼錶,須要在輸出流以前設置。
//設置Response查詢的碼錶
//response.setCharacterEncoding("UTF-8");
//經過一個頭Content-Type,告知客戶端使用的編碼表
//response.setHeader("Content-Type", "text/html;charset=UTF-8");
//封裝的方法
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write("hello China");
writer.write("中國!!!");
PrintWriter getWriter()
得到字符流,經過字符流的write(String s)方法能夠將字符串設置到response 緩衝區中,隨後Tomcat會將response緩衝區中的內容組裝成Http響應返回給瀏覽器端。
關於設置中文的亂碼問題
緣由:response緩衝區的默認編碼是iso8859-1,此碼錶中沒有中文,能夠經過response的setCharacterEncoding(String charset) 設置response的編碼。
但咱們發現客戶端仍是不能正常顯示文字
緣由:咱們將response緩衝區的編碼設置成UTF-8,但瀏覽器的默認編碼是本地系統的編碼,由於咱們都是中文系統,因此客戶端瀏覽器的默認編碼是GBK,咱們能夠手動修改瀏覽器的編碼是UTF-8。咱們還能夠在代碼中指定瀏覽器解析頁面的編碼方式,經過response的setContentType(String type)方法指定頁面解析時的編碼是UTF-
8。response.setContentType("text/html;charset=UTF-8");
上面的代碼不只能夠指定瀏覽器解析頁面時的編碼,同時也內含setCharacterEncoding的功能,因此在實際開發中只要編寫
response.setContentType("text/html;charset=UTF-8");
就能夠解決頁面輸出中文亂碼問題。
注意:上述紅色代碼只能在response頁面輸出前生效,若是頁面先有輸出(非中文等),再寫上述代碼,再輸出中文,仍是不能解決中文亂碼問題。
b、響應頭設置字節
//使用response得到字節輸出流
ServletOutputStream outputStream = response.getOutputStream();
得到字節流,經過該字節流的write(byte[] bytes)能夠向response緩衝區中寫入字節,再由Tomcat服務器將字節內容組成Http響應返回給瀏覽器。
//使用response得到字節輸出流
ServletOutputStream outputStream = response.getOutputStream();
//得到服務器上的圖片
String realPath = this.getServletContext().getRealPath("/WEB-INF/a.jpg");
InputStream in = new FileInputStream(realPath);
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer))>0) {
outputStream.write(buffer, 0, len);
}
in.close();
outputStream.close();
2、文件下載的基本代碼
問題:
a、什麼狀況下會文件下載?
瀏覽器不能解析的文件就下載。
b、什麼狀況下須要在服務器端編寫文件下載的代碼?
理論上,瀏覽器能夠解析的代碼須要編寫文件下載代碼。
實際開發中,只要是下載的文件都編寫文件代碼下載。
一、文件下載的本質
文件下載的實質就是文件拷貝,將文件從服務器端拷貝到瀏覽器端。因此文件下載須要IO技術將服務器端的文件使用InputStream讀取到,再使用ServletOutputStream寫到response緩衝區中。
//使用response得到字節輸出流
ServletOutputStream outputStream = response.getOutputStream();
//得到服務器上的圖片
String realPath = this.getServletContext().getRealPath("/WEB-INF/a.jpg");
InputStream in = new FileInputStream(realPath);
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer))>0) {
outputStream.write(buffer, 0, len);
}
in.close();
outputStream.close();
上述代碼能夠將圖片從服務器端產生到瀏覽器,但瀏覽器直接解析圖片顯示在頁面上,而不是提供下載,咱們須要設置兩個響應頭,告知瀏覽器文件的類型和文件的打開方式。
a、告知瀏覽器文件的類型:
response.setContentType(文件的MIME類型)
response.setContentType(this.getServletContext().getMimeType(filename));
b、告知瀏覽器文件的打開方式是下載:
response.setHeader("Content-Disposition","attachment;filename=文件名稱");
//告訴客戶端該文件不是直接解析,而是以附件形式打開(下載)
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//得到要下載文件的名稱
String filename = request.getParameter("filename");
//要下載的這個文件的類型-----客戶端經過文件的MIME類型去區分類型
//MIME:字符串
response.setContentType(this.getServletContext().getMimeType(filename));
//告訴客戶端該文件不是直接解析,而是以附件形式打開(下載)
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//得到文件的絕對路徑
String realPath = this.getServletContext().getRealPath("download/" + filename);
//得到該文件的輸入流
InputStream in = new FileInputStream(realPath);
//得到輸出流--經過response得到的輸出流,用於向客戶端寫內容
ServletOutputStream out = response.getOutputStream();
//文件拷貝的模板代碼
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) >0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
解決亂碼的問題:
解決亂碼方法以下(不要記憶--瞭解):
if (agent.contains("MSIE")) {
// IE瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
}
download.html
<body>
<h1>使用服務器編碼實現文件下載</h1>
<a href="/WEB14_Response/downloadServlet?filename=a.flv">a.flv</a><br>
<a href="/WEB14_Response/downloadServlet?filename=a.jpg">a.jgp</a><br>
<a href="/WEB14_Response/downloadServlet?filename=a.mp3">a.mp3</a><br>
<a href="/WEB14_Response/downloadServlet?filename=a.mp4">a.mp4</a><br>
<a href="/WEB14_Response/downloadServlet?filename=a.txt">a.txt</a><br>
<a href="/WEB14_Response/downloadServlet?filename=a.zip">a.zip</a><br>
<a href="/WEB14_Response/downloadEncode?filename=美女.jpg">美女.jpg</a><br>
</body>
downloadEncodeServlet.java
//得到要下載文件的名稱
String filename = request.getParameter("filename"); //美女.jpg
System.out.println(filename);
//解決得到中文參數的亂碼
//filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");
//得到請求頭中的User-Agent
String agent = request.getHeader("User-Agent");
String filenameEncode = "";
//根據不一樣得了瀏覽器進行不一樣的編碼
if (agent.contains("MSIE")) {
// IE瀏覽器
filenameEncode = URLEncoder.encode(filename, "utf-8");
filenameEncode = filenameEncode.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncode = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filenameEncode = URLEncoder.encode(filename, "utf-8");
}
//要下載的這個文件的類型-----客戶端經過文件的MIME類型去區分類型
//MIME:字符串
response.setContentType(this.getServletContext().getMimeType(filename));
//告訴客戶端該文件不是直接解析,而是以附件形式打開(下載)
response.setHeader("Content-Disposition", "attachment;filename="+filenameEncode);
//得到文件的絕對路徑
String realPath = this.getServletContext().getRealPath("download/" + filename);
//System.out.println("realPath:"+realPath);
//得到該文件的輸入流
InputStream in = new FileInputStream(realPath);
//得到輸出流--經過response得到的輸出流,用於向客戶端寫內容
ServletOutputStream out = response.getOutputStream();
//文件拷貝的模板代碼
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) >0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
其中agent就是請求頭User-Agent的值。
response細節點:
a、response 得到的流不須要手動關閉,Tomcat容器會幫助咱們關閉
b、getWriter 和 getOutputStream不能同時調用
java下載文件的中文名 爲何要用 new String(fileName.getBytes("gb2312"),"iso8859-1");緣由是什麼?
3、實現驗證碼功能
經過java代碼或者其餘生產驗證碼的過程,不須要很瞭解。可是生產的驗證碼圖片,須要掌握怎樣使用!!!