web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

service方法中的response的類型是ServletResponse,而doGet/doPost方法的response的類型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加強大

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

從圖片可以看出,response寫入數據到緩衝區之後,tomcat引擎還會從緩衝區中取出數據,並且tomcat還會給其加上請求行和請求頭封裝成響應頭。

tomcat可以給封裝,其實response也可以自己設置響應頭,自己設計的內容,tomcat就不會再給補充了,它只會補充沒有設置的內容,常用的response 的方法

設置響應行的狀態碼setStatus(int sc)

1.通過response設置響應頭

addHeader(String name, String value)addIntHeader(String name, int value)addDateHeader(String name, long date)------------------------------------------------------setHeader(String name, String value) 常用setDateHeader(String name, long date)setIntHeader(String name, int value)其中,add表示添加,而set表示設置一個是設置一個是添加,這兩個是有區別的,添加的話,相同那麼的添加都會保留設置的話,後面一個會覆蓋前面一個
web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

通過這個代碼可以看出來,連續設置了兩個name結果是兩個都保存

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

這個是設置,重複的name,結果是前面的28被覆蓋了,只留下了50

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

js實現頁面倒計時跳轉

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

重定向

重定向簡單解釋就是說,客服端尋找A資源,A資源告訴客戶端去找B資源,然後客戶端就去訪問了B資源,注意這個過程會體現在瀏覽器的地址欄上

重定向實現分兩步

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

這個過程的意思就是說讓服務器去訪問servlet2,這個/web14/servlet2url路徑資源的寫法要注意,直接從應用開始寫

上面每次寫兩步太費事了,後來就給封裝了

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

效果是一樣的

response的編碼問題

原因:response緩衝區的默認編碼是iso8859-1,此碼錶中沒有中文,可以通過response的setCharacterEncoding(String charset) 設置response的編碼但我們發現客戶端還是不能正常顯示文字原因:我們將response緩衝區的編碼設置成UTF-8,但瀏覽器的默認編碼是本地系統的編碼,因為我們都是中文系統,所以客戶端瀏覽器的默認編碼是GBK,我們可以手動修改瀏覽器的編碼是UTF-8。我們還可以在代碼中指定瀏覽器解析頁面的編碼方式,通過response的setContentType(String type)方法指定頁面解析時的編碼是UTF-8response.setContentType("text/xml;charset=UTF-8");上面的代碼不僅可以指定瀏覽器解析頁面時的編碼,同時也內含setCharacterEncoding的功能,所以在實際開發中只要編寫response.setContentType("text/xml;charset=UTF-8");response.setContentType("text/xml;charset=UTF-8");要在獲得writer之前寫這樣獲得的writer才是utf-8的writer

response的的寫問題

response可以獲取字節流的寫,還可以獲取字符流的寫,

ServletOutputStream getOutputStream()

PrintWriter getWriter()

這是兩個方法, getOutputStream()返回ServletOutputStream, getWriter()返回PrintWriter

實例,response向客戶端寫入一張圖片

既然是一張圖片,那麼肯定是需要子節流來操作了

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

package com.huanfeng.cn;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Picture extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String path=this.getServletContext().getRealPath("1111.png");InputStream in=new FileInputStream(path);ServletOutputStream sos=response.getOutputStream();int len=0;byte[] b=new byte[1024];while((len=in.read(b))!=-1) {sos.write(b,0,len);}in.close();sos.close();}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

response實現文件下載

剛才上面實現了寫入,其實下載的核心就是response寫入到客戶端,但要補充一些東西

先寫一個下載鏈接

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

因為客戶端去訪問服務器端,所以需要帶著應用名WWW,就像是在地址欄輸入地址一樣,我們訪問web應用都會帶著應用名的

這個href就是web端的資源路徑,只要在瀏覽器點擊,就可以下載或者瀏覽,比如flv視頻文件可以下載

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

但是點擊圖片鏈接卻只能瀏覽卻不能下載,這就不是我們想要的功能了,原因是瀏覽器可以直接解析圖片顯示在頁面上,那麼我們可以通過設置兩個響應頭,告知瀏覽器文件的類型和文件的打開方式。

1)告知瀏覽器文件的類型:response.setContentType(文件的MIME類型);文件的Mime類型可以通過this.getServletContext().getMimeType(filename)來獲得2)告示瀏覽器文件的打開方式是下載:response.setHeader("Content-Disposition","attachment;filename=文件名稱");

第一個告訴瀏覽器當前資源的類型,第二個告訴瀏覽器就算你能解析,你也不要解析,而是下載

1,2代碼只能寫在servlet內,所以我們要把這些代碼寫到servlet,那麼相應的download.html的href標籤應該鏈接到servlet,並且告知servlet自己所鏈接的文件的名稱

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

這個地址也是在地址欄的訪問servlet的標準形式,點擊鏈接就將跳轉到servlet,我們要在servlet寫上

告訴瀏覽器當前資源的類型,第二個告訴瀏覽器就算你能解析,你也不要解析,而是下載的代碼

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

寫上這個代碼之後,點擊所有的鏈接,他都不會下載了,然後像上面的輸出代碼一樣輸出filename向瀏覽器就完成下載工作了

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

這樣即使是點擊a.jpg圖片也不是解析了,而是下載操作,點擊保存就可以完成下載

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

但是還有一個小問題需要解決,比如當我們web的資源名稱為中文時會有亂碼,比如將mp3音樂的歌曲,改為中文

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

頁面改為歌曲,那麼調到web服務器的時候獲取參數的時候,歌曲兩個字會使用ISO8859-1的方式解碼找對應中文,因為ISO8859-1沒有中文,所以這種解碼方式必然會出現問題,所以我們應該將filename先按照ISO8859-1編碼,然後在按照utf-8解碼,就可以解決編碼問題,獲取中文歌曲

filename=new String(filename.getBytes("ISO8859-1"),"UTF-8"),這個有的時候運行不成可以直接使用

URLEncoder.encode(filename, "UTF-8");

這個解決之後,我們在運行一下

web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?

這個可以下載了,能找到對應的圖片了,但是又有了亂碼不顯示圖片.png

但是,如果下載中文文件,頁面在下載時會出現中文亂碼或不能顯示文件名的情況, 原因是不同的瀏覽器默認對下載文件的編碼方式不同,ie是UTF-8編碼方式,而火狐 瀏覽器是Base64編碼方式。所裡這裡需要解決瀏覽器兼容性問題,解決瀏覽器兼容 性問題的首要任務是要辨別訪問者是ie還是火狐(其他),通過Http請求體中的一 個屬性可以辨別

//獲得請求頭中的User-AgentString agent = request.getHeader("User-Agent");//根據不同瀏覽器進行不同的編碼String filenameEncoder = "";if (agent.contains("MSIE")) {// IE瀏覽器filenameEncoder = URLEncoder.encode(filename, "utf-8");filenameEncoder = filenameEncoder.replace("+", " ");} else if (agent.contains("Firefox")) {// 火狐瀏覽器BASE64Encoder base64Encoder = new BASE64Encoder();filenameEncoder = "=?utf-8?B?"+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";} else {// 其它瀏覽器filenameEncoder = URLEncoder.encode(filename, "utf-8");}可運行運行版package com.huanfeng.cn;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Download extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//獲得要下載的文件的名稱String filename = request.getParameter("filename");URLEncoder.encode(filename, "UTF-8");//要下載的這個文件的類型-----客戶端通過文件的MIME類型去區分類型response.setContentType(this.getServletContext().getMimeType(filename));//告訴客戶端該文件不是直接解析 而是以附件形式打開(下載)response.setHeader("Content-Disposition", "attachment;filename="+filename);String path=this.getServletContext().getRealPath("download/"+filename);InputStream in=new FileInputStream(path);ServletOutputStream sos=response.getOutputStream();int len=0;byte[] b=new byte[1024];while((len=in.read(b))!=-1) {sos.write(b,0,len);}in.close();}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

完整版

package com.itheima.content;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import sun.misc.BASE64Encoder;public class DownLoadServlet2 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//*******文件名稱是中文的下載*******//獲得要下載的文件的名稱String filename = request.getParameter("filename");//????.jpg//解決獲得中文參數的亂碼----下節課講filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg//獲得請求頭中的User-AgentString agent = request.getHeader("User-Agent");//根據不同瀏覽器進行不同的編碼String filenameEncoder = "";if (agent.contains("MSIE")) {// IE瀏覽器filenameEncoder = URLEncoder.encode(filename, "utf-8");filenameEncoder = filenameEncoder.replace("+", " ");} else if (agent.contains("Firefox")) {// 火狐瀏覽器BASE64Encoder base64Encoder = new BASE64Encoder();filenameEncoder = "=?utf-8?B?"+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";} else {// 其它瀏覽器filenameEncoder = URLEncoder.encode(filename, "utf-8");}//要下載的這個文件的類型-----客戶端通過文件的MIME類型去區分類型response.setContentType(this.getServletContext().getMimeType(filename));//告訴客戶端該文件不是直接解析 而是以附件形式打開(下載)----filename="+filename 客戶端默認對名字進行解碼response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);//獲取文件的絕對路徑String path = this.getServletContext().getRealPath("download/"+filename);//獲得該文件的輸入流InputStream in = new FileInputStream(path);//獲得輸出流---通過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();}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
web開發:HttpServletResponse是什麼,怎麼使用,用在什麼地方?


分享到:


相關文章: