Response

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");
替代上面代碼。
 
設置定時刷新,也可以達到重定向的功能!
//設置定時刷新的頭,5秒回刷新到百度
             response.setHeader("refresh", "5;url=http://www.baidu.com";);
 
四、經過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代碼或者其餘生產驗證碼的過程,不須要很瞭解。可是生產的驗證碼圖片,須要掌握怎樣使用!!!
相關文章
相關標籤/搜索