Web服務器收到客戶端的http請求,會針對每一次請求,分別創建一個用於代表請求的request對象、和代表響應的response對象。獲取網頁提交過來的數據,只需要找request對象就行了。要向網頁輸出數據,只需要找response對象。
一,HttpServletResponse對象介紹
HttpServletResponse對象代表服務器的響應。這個對象中封裝了向客戶端發送數據、發送響應頭,發送響應狀態碼的方法。
二,HttpServletResponse對象常用方法
1,負責向客戶端(瀏覽器)發送數據的相關方法
getOutputStream() |
該方法用於返回Servlet引擎創建的字節輸出流對象,Servlet程序可以按字節形式輸出響應正文。 |
getWriter() |
該方法用於返回Servlet引擎創建的字符輸出流對象,Servlet程序可以按字符形式輸出響應正文。 |
注意:
1,getOutputStream()和getWriter()這兩個方法互相排斥,調用了其中的任何一個方法后,就不能再調用另一方法。
2,getOutputStream()返回的字節輸出流對象,類型為:ServletOutputStream,直接輸出字節數組中的二進制數據。
3,getWriter()方法將Servlet引擎的數據緩沖區包裝成P:rintWriter類型的字符輸出流對象后返回,PrintWriter對象只能輸出字符文本內容。
2,負責向客戶端(瀏覽器)發送響應頭的相關方法
addDateHeader(String name ,long date) |
該方法是設置只有一個值且值的類型為long類型的響應頭,例如expies響應頭,表示過期時間 |
addHeader(String name,String value) |
該方法是設置有多個值的響應頭,參數name表示響應頭名稱,參數value表示響應頭的值 |
addIntHeader(String name,int value) |
該方法是設置有多個值且值的類型為int類型的響應頭 |
setHeader(String name,String value) |
該方法是設置只有一個值的響應頭,參數name表示響應頭名稱,參數value表示響應頭的值 |
setDateHeader(String name,long value) |
該方法是設置只有一個值且值的類型為long類型的響應頭,例如expies響應頭,表示過期時間 |
setIntHeader(String name,int value) |
該方法是設置只有一個值且值的類型為int類型的響應頭,例如Content-Length響應頭,該響應頭是代表響應內容有多少字節數 |
//設置Content-Type響應頭 resp.setHeader("Content-Type","text/html;charset=utf-8"); //添加一個響應頭:xxx是表示某一響應頭 resp.addHeader("xxx", "123"); //通知客戶端響應內容長度為888個字節 resp.setIntHeader("Context-Length", 5); //設置過期時間為:5000毫秒 resp.setDateHeader("", 5000);
3,負責向客戶端(瀏覽器)發送響應狀態碼的相關方法
setStatus(int value) |
設置臨時定向響應碼 |
4,響應狀態碼的常量
HttpServletResponse定義了很多狀態碼的常量(具體可以查看Servlet的API),當需要向客戶端發送響應狀態碼時,可以使用這些常量,避免了直接寫數字,常見的狀態碼對應的常量:
SC_NOT_FOUND |
狀態碼404對應的常量 |
SC_OK |
狀態碼200對應的常量 |
SC_INIERNAL_SERVER_ERROR |
狀態碼500對應的常量 |
三,HttpServletResponse對象常見應用
1,向客戶端瀏覽器輸出數據
例子1:使用OutputStream流向客戶端瀏覽器輸出數據
public class HelloResponse extends HttpServlet{ private static final long serialVersionUID = 3903946972744326948L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //設置Content-Type響應頭,編碼格式為UTF-8 resp.setHeader("Content-Type","text/html;charset=utf-8"); outPutOutputStream(resp); } /** * * @方法名: outPutOutputStream * @描述: 使用OutputStream輸出流輸出數據 * @param resp * @throws IOException * @創建人 zender */ private void outPutOutputStream(HttpServletResponse resp) throws IOException{ String data = "輸出的內容"; //獲取OutputStream輸出流 OutputStream outputStream = resp.getOutputStream(); //將字符轉換成字節數組,指定以UTF-8編碼進行轉換 byte[] dataByteArr = data.getBytes("UTF-8"); //使用OutputStream流向客戶端輸出字節數組 outputStream.write(dataByteArr); } }
運行結果如下:
例子2:使用PrintWriter流向客戶端瀏覽器輸出數據
public class PrintWriterResponse extends HttpServlet{ private static final long serialVersionUID = 3903946972744326948L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //設置編碼格式為UTF-8 resp.setCharacterEncoding("UTF-8"); //通過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據,如果不加這句話,那么瀏覽器顯示的將是亂碼 resp.setHeader("content-type", "text/html;charset=UTF-8"); outPutPrintWriter(resp); } /** * * @方法名: outPutPrintWriter * @描述: 使用PrintWriter輸出流輸出數據 * @param resp * @throws IOException * @創建人 zender */ private void outPutPrintWriter(HttpServletResponse resp) throws IOException{ String data = "輸出的內容"; //獲取PrintWriter輸出流 PrintWriter out = resp.getWriter(); //使用PrintWriter流向客戶端輸出字符 out.write(data); } }
運行結果如下:
注意:
1,在獲取PrintWriter輸出流之前首先使用"response.setCharacterEncoding(charset)"設置字符以什么樣的編碼輸出到瀏覽器,再使用response.getWriter();獲取PrintWriter輸出流,這兩個步驟不能顛倒。
2,在開發過程中,如果希望服務器輸出什么瀏覽器就能看到什么,那么在服務器端都要以字符串的形式進行輸出。
2,文件下載
文件下載功能是web開發中經常使用到的功能,使用HttpServletResponse對象就可以實現文件的下載。
文件下載功能的實現思路:
1,獲取要下載的文件的絕對路徑
2,獲取要下載的文件名
3,設置content-disposition響應頭控制瀏覽器以下載的形式打開文件
4,獲取要下載的文件輸入流
5,創建數據緩沖區
6,通過response對象獲取OutputStream流
7,將FileInputStream流寫入到buffer緩沖區
8,使用OutputStream將緩沖區的數據輸出到客戶端瀏覽器
public class FileDownloadResponse extends HttpServlet{ private static final long serialVersionUID = 3903946972744326948L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取要下載的文件的絕對路徑 String realPath = this.getServletContext().getRealPath("/下載.png"); //獲取要下載的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); //設置content-disposition響應頭控制瀏覽器以下載的形式打開文件 //中文文件名要使用URLEncoder.encode方法進行編碼,否則會出現文件名亂碼 resp.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); //獲取文件輸入流 InputStream in = new FileInputStream(realPath); int len = 0; byte[] buffer = new byte[1024]; OutputStream out = resp.getOutputStream(); while ((len = in.read(buffer)) > 0) { out.write(buffer,0,len);//將緩沖區的數據輸出到客戶端瀏覽器 } in.close(); out.close(); } }
注意:
推薦使用OutputStream流,避免使用PrintWriter流,因為OutputStream流是字節流,可以處理任意類型的數據,而PrintWriter流是字符流,只能處理字符數據,如果用字符流處理字節數據,會導致數據丟失。
4,設置響應頭控制瀏覽器的行為
1,定時刷新頁面
response.setHeader("refresh", "5");//設置refresh響應頭控制瀏覽器每隔5秒鍾刷新一次 |
2,禁止緩存當前文檔內容
response.setDateHeader("expries", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); |
3,重定向
什么是重定向:一個web資源收到客戶端請求后,通知客戶端去訪問另外一個web資源,這稱之為請求重定向。
例如:
public class RedirectResponse extends HttpServlet{ private static final long serialVersionUID = 3903946972744326948L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //endRedirect方法實現請求重定向 resp.sendRedirect(req.getContextPath() + "/index.jsp"); } }
訪問:http://localhost:8081/ServletDemo/RedirectResponse.html,瀏覽器會跳轉到:http://localhost:8081/ServletDemo/index.jsp