板塊一 Servlet編程:第四節 HttpServletResponse對象全解與重定向 來自【湯米尼克的JAVAEE全套教程專欄】

板塊一 Servlet編程:第四節 HttpServletResponse對象全解與重定向

  • 一、什么是HttpServletResponse
  • 二、響應數據的常用方法
  • 三、響應亂碼問題
      • 字符流亂碼
      • 字節流亂碼
  • 四、重定向:sendRedirect
      • 請求轉發和重定向的區別

在上一節中,我們系統的學習了請求響應在Servlet中service()方法的第一個形參HttpServletRequest(請求)對象,這一節中我們將學習它的兄弟,service()方法的第二個形參HttpServletResponse(響應)對象

一、什么是HttpServletResponse

在我們已然熟悉的瀏覽器訪問Servlet的過程中。Request和Response 對象分別代表請求和響應:通過Request對象獲取客戶端數據;通過 Response 對象向客戶端輸出數據:
在這里插入圖片描述
service()方法中形參接收的是HttpServletResponse接口的實例化對象,它繼承自ServletResponse接口,專門用來封裝HTTP響應消息,由于HTTP響應消息分為狀態行響應消息頭消息體三部分(詳見HTTP協議理論與服務器請求響應原理小節),因此在HttpServletResponse中定義了狀態行、響應消息頭、消息體三部分。

  • 狀態行部分
    響應消息頭包含了關于響應的附加信息,例如內容類型、內容長度、緩存控制等。由setStatus(int status)方法實現,該方法用于設置HTTP響應消息的狀態碼,并生成相應代碼;默認會生成一個狀態碼為200的狀態行;
  • 響應消息頭部分
    響應消息頭包含了關于響應的附加信息,例如內容類型、內容長度、緩存控制等。可以使用setHeader(String name, String value)方法設置響應消息頭的字段和值,例如setHeader("Content-Type", "text/html")設置內容類型為HTML。如果要設置相同字段的多個值,可以使用addHeader(String name, String value)方法,例如addHeader("Set-Cookie", "cookie1=value1")。此外還可以使用一些特定的方法來設置常見的響應消息頭,例如setContentType(String type)setContentLength(int len)
  • 消息體部分
    消息體包含了實際的響應數據。可以通過獲取ServletOutputStream或PrintWriter對象來寫入響應消息體。getOutputStream()方法返回一個可以寫入二進制數據的ServletOutputStream對象。
    getWriter()方法返回一個可以寫入字符數據的PrintWriter對象。
    可以使用這些對象的方法將數據寫入響應消息體,例如print(String s)、write(byte[] b)等。

二、響應數據的常用方法

接收到客戶端請求后,可以通過HttpServletResponse對象直接進行響應,響應時需要獲取輸出流。
有兩種形式:

  • getWriter() 獲取字符流(只能響應字符串)
  • getOutputStream() 獲取字節流(能響應一切數據)

響應回的數據到客戶端被瀏覽器解析
注意:兩者不能同時使用

實例
在start.java導入PrintWriter類,并在service()中寫入測試代碼

// 獲取字符輸出流
PrintWriter writer = resp.getWriter();
//輸出數據
writer.write("Hello");

啟動服務器,在瀏覽器中訪問得
在這里插入圖片描述
在start.java中導入ServletOutputStream類,并在service()中寫入測試代碼

//得到字節輸出流
ServletOutputStream out = resp.getOutputStream();
// 輸出數據
out.write("Hi".getBytes());

啟動服務器,在瀏覽器中訪問得
在這里插入圖片描述
但當兩者同時使用時
start.java

package www.caijiyuan;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet("/start")
public class start extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 獲取字符輸出流PrintWriter writer = resp.getWriter();//輸出數據writer.write("Hello");//得到字節輸出流ServletOutputStream out = resp.getOutputStream();// 輸出數據out.write("Hi".getBytes());}
}

啟動服務器,在瀏覽器中訪問,只得到了第一個的打印內容
在這里插入圖片描述
這是為什么呢?查看報錯信息
在這里插入圖片描述原來是getWriter()已經調用過response對象了,如果再響應一次response對象就已經不存在了

三、響應亂碼問題

在上一節中我們使用request.setCharacterEncoding("UTF-8");解決了請求時中文亂碼的問題,同樣,在響應時也存在中文亂碼問題。這是因為服務器響應的數據也會經過網絡傳輸,服務器端有一種編碼方式,在客戶端也存在一種編碼方式,當兩端使用的編碼方式不同時則出現亂碼。

字符流亂碼

對于getWriter()獲取到的字符流,響應中文必定出亂碼,由于服務器端在進行編碼時默認會使用ISO-8859-1格式的編碼,該編碼方式并不支持中文。要解決該種亂碼只能在服務器端告知服務器使用一種能夠支持中文的編碼格式,這也是我們在解決請求時中文亂碼的方法

response.setCharacterEncoding("UTF-8");

此時還只完成了一半的工作
要保證數據正確顯示,還需要指定客戶端的解碼方式

response.setHeader("content-type", "text/html; charset=UTF-8");

兩端指定編碼后,亂碼就解決了。一句話:保證發送端接收端編碼一致

實例
我們在start.java的service()中寫入測試測試代碼,試圖打印中文

// 獲取字符輸出流
PrintWriter writer = resp.getWriter();
//輸出數據
writer.write("湯米尼克");

啟動服務器,在瀏覽器中訪問,發現輸出中文亂碼
在這里插入圖片描述
設置服務器和客戶端的編碼格式統一

// 設置服務端的編碼
resp.setCharacterEncoding("UTF-8");
// 設置客戶端的響應類型及編碼
resp. setHeader("content-type", "text/html; charset=UTF-8");
// 獲取字符輸出流
PrintWriter writer = resp.getWriter();
// 輸出數據
writer.write("湯米尼克");

重啟瀏覽器,再在瀏覽器中訪問就解決問題了
在這里插入圖片描述
理解了原理,其實我們還可以同時設置客戶端和服務端的編碼方式

response.setContentType( "text/html; charset=UTF-8");

這一句就可以替換上面的兩句

字節流亂碼

對于getOutputStream()方式獲取到的字節流,響應中文時,由于本身就是傳輸的字節,所以此時可能出現亂碼,也可能正確顯示。當服務器端給的字節恰好和客戶端使用的編碼方式一致時則文本正確顯示,否則出現亂碼。無論如何我們都應該準確掌握服務器和客戶端使用的是那種編碼格式,以確保數據正確顯示。
因此,字節流亂碼的解決方式與上面字符流亂碼的解決方式一樣,在響應發出之前同時設置服務器和客戶端的編碼格式統一即可

response.setContentType( "text/html; charset=UTF-8");

四、重定向:sendRedirect

重定向是一種服務器為指導的客戶端行為
怎么理解這句話呢?客戶端發出一個請求,被服務器接收處理后進行響應,在響應的同時,服務器會給客戶端一個新的地址(下次請求的地址),當客戶端接收到響應后,會立刻、馬上自動根據服務器給的新地址發起第二個請求,服務器接收請求并作出響應,重定向完成。可以看出這個過程中有兩個請求存在,其中兩個Servlet的Request對象并不共享、不能傳值,屬于客戶端行為。

在Servlet中重定向的語句為

response.sendRedirect("url");

實例:從start.java重定向到after.java的過程
在start.java的service()中寫入重定向前的測試代碼

System.out.println("這里是start");
resp.sendRedirect("after");

在after.java的service()中寫入重定向到底測試代碼

System.out.println("這里是after");

啟動服務器,在瀏覽器中輸入start的地址
在這里插入圖片描述
回車訪問后地址立即跳轉到after,說明重定向的地址欄會發生改變
在這里插入圖片描述
同時控制臺輸出了
在這里插入圖片描述
那么重定向在服務器中的響應頭是如何實現的?
如下圖,在開發者工具中打開響應頭的內容
在這里插入圖片描述
會發現start文件響應行的狀態碼是302,這就是重定向的狀態碼
并且響應頭鍵值對中Location鍵的值就是要重定向到的地址:after文件
這與我們在第一節 HTTP協議理論與服務器請求響應原理中學習的響應頭的知識首尾呼應起來了

請求轉發和重定向的區別

上一節中我們學習了Request對象的請求轉發,這一節又學習了Response對象的重定向,兩兄弟讓人傻傻分不清,必須好好區分區分

請求轉發重定向
request.getRequestDispatcher("url").forward(request, response);response.sendRedirect("url");
服務器端行為客戶端行為
一次請求,Request域中數據共享兩次請求,Request域中數據不共享
地址欄不發生變化地址欄發生變化
跳轉只能在當前站點內跳轉任意地址

在這一節中我們學習了HttpServletResponse對象,學習了字符流字節流響應方法、重定向方法。不禁思考,Servlet作為“后端”,在Web交互中最重要的作用就是傳遞各種數據,但目前我們學到的傳值的方法還知之甚少,在下一節中我們將學習Cookie對象、HttpSession對象、ServletContext對象,它們作為不同特點的容器在Servlet上可以實現不同范圍的傳值

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697239.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697239.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697239.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

學習C++,你不能錯過這4個編程軟件

作為一門起源比較早的編程語言,C應用的范圍非常廣,編程軟件自然也非常多。今天小編給大家簡單介紹4個不錯的C編程軟件,感興趣的小伙伴可以去嘗試一下。 1、visual studio Microsoft visual studio community 15/17(一般簡稱vs),…

jdwp-event command Set

Event Command Set (64) Composite (100) 事件命令集 (64) 復合命令 (100) 目標虛擬機中的給定時間可能會發生多個事件。 例如,給定位置可能有多個斷點請求,或者您可能單步執行到與斷點請求相同的位置。 這些事件作為復合事件一起傳遞。 為了統一&#x…

redis:數據傾斜是什么?怎么應對熱點數據?

要知道什么是數據傾斜就的搞清楚redis是怎么存儲和訪問數據的。數據會按照一定的規則分布到不同槽上,然后槽又落在不同的機器節點上。比如把key進行crc16函數計算后的值對槽取模,然后槽會分配到不同的節點上。然后存取都會到對應的節點上去進行處理。 傾…

黑色金屬冶煉5G智能工廠數字孿生可視化管控系統,推進金屬冶煉行業數字化轉型

黑色金屬冶煉5G智能工廠數字孿生可視化管控系統,推進金屬冶煉行業數字化轉型。隨著科技的不斷發展,數字化轉型已經成為各行各業發展的必然趨勢。金屬冶煉行業作為傳統工業的重要組成部分,也面臨著數字化轉型的挑戰和機遇。為了推進金屬冶煉行…

在 Windows 上使用 VC++ 編譯 OpenSSL 源碼的步驟

在 Windows 上使用 VC 編譯 OpenSSL 源碼的步驟如下: 準備工作 安裝 Visual Studio 2017 或更高版本。安裝 Perl 腳本解釋器。安裝 NASM 匯編器。 編譯步驟 下載 OpenSSL 源碼。解壓 OpenSSL 源碼。打開命令行工具,并進入 OpenSSL 源碼目錄。運行以下…

Sublime text 3 配置

1.下載 打開官網鏈接:Download - Sublime Text或者去百度軟件中心搜索sublimeText3(根據自己的實際情況下載對應的版本) 2.安裝: 雙擊上一步下載下來的“Sublime Text Build 3083 x64 Setup.exe”,記得選擇“Add to…

IT資訊——全速推進“AI+鴻蒙”戰略布局!

文章目錄 每日一句正能量前言堅持長期研發投入全速推進“AI鴻蒙”戰略 人才戰略新章落地持續加碼核心技術生態建設 后記 每日一句正能量 人總要咽下一些委屈,然后一字不提的擦干眼淚往前走,沒有人能像白紙一樣沒有故事,成長的代價就是失去原來…

2023 龍蜥操作系統大會演講實錄:《兼容龍蜥的云原生大模型數據計算系統——πDataCS》

本文主要分三部分內容:第一部分介紹拓數派公司,第二部分介紹 πDataCS 產品,最后介紹 πDataCS 與龍蜥在生態上的合作。 杭州拓數派科技發展有限公司(簡稱“拓數派”,英文名稱“OpenPie”)是國內基礎數據計…

論文發表 | 頂會頂刊的實驗是如何煉成的

前言:Hello大家好,我是小哥談。在計算機科學研究領域,尤其是當你追求頂級會議和期刊的發表時,沒有什么?實驗設計更關鍵了。為什么這么說?理由很簡單。實驗不僅僅是你?來 檢驗假設的?段,它更是審稿?會重點關注和閱讀的部分,也是你驗證??研究多么創新、多么重要的內…

0221 解決萬得導出數據excel無法python讀入的問題

報錯如下&#xff1a; TypeError: <class openpyxl.styles.named_styles._NamedCellStyle>.name should be <class str> but value is <class NoneType> 原因分析&#xff1a; 萬得導出的xlsx帶有某些格式&#xff0c;比如首行加粗&#xff0c;excel桌面端工…

Linux之用戶和用戶組

目錄 一、簡介 1.1 用戶賬號分類 二、用戶 2.1 useradd 2.2 userdel 2.3 usermod 2.4 passwd 2.5 su 2.6 登出 三、用戶組 3.1 groupadd 3.2 groupdel 3.3 groupmod 3.4 newgrp 四、用戶賬號系統 4.1 /ect/passwd 4.2 常見的偽用戶如下所示 五、思維導圖 …

自動駕駛---Motion Planning之LaneChange

1 背景 在Apollo中,有比較多的Decider(決策器),上篇博客《自動駕駛---Motion Planning之Decider》中筆者也大概介紹了每個Deicder的作用。 本篇博客筆者主要介紹換道的決策內容,因為在自動駕駛中(嚴格意義上來講,目前還屬于輔助駕駛),變道的靈活性是用戶評價該功能是否…

安裝和配置awscli

1、 安裝awscli curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip ./aws/install ln -s /usr/local/bin/aws /usr/bin/aws安裝完成&#xff0c;檢查awscli版本號 aws --version輸出內容 aws-cli…

igolang學習3,golang 項目中配置gin的web框架

1.go 初始化 mod文件 go mod init gin-ranking 2.gin的crm框架 go get -u github.com/gin-gonic/gin 3.go.mod爆紅解決

Odoo17 不再支持視圖中的attrs和states

在最新的視圖設計中&#xff0c;屬性寫法發生了改變。以前我們使用的attrs和states屬性不再被支持&#xff0c;因此在現有模塊的視圖中&#xff0c;之前寫在attrs屬性中的invisiable、readonly、required等屬性需要全部拆分成獨立的屬性表達式。 odoo17之前的寫法 <field …

回調函數(Language C)

#源于指針的深入學習 對于回調函數&#xff0c;其實我們只需要了解一下函數指針即可使用回調函數了 什么是回調函數&#xff1f; 通俗的來講&#xff0c;它是一個函數指針變量&#xff08;注意&#xff1a;它不是指針函數&#xff0c;它們是不同的一個概念&#xff09; 函數…

靡語IT:JavaScript_概述、基礎

一、JavaScript 概述 javaScript 語言主要是完成頁面的數據驗證&#xff0c;因此它運行在客戶端&#xff0c; 需要運行瀏覽器來解析執行 JavaScript 代碼。js 是網景公司 &#xff08;Netscape&#xff09;的產品&#xff0c;最早取名為 LiveScript 最后借 java 的熱度 改為 j…

C++多線程同步(上)

多線程同步 引言總述詳情互斥鎖示例運行結果分析條件變量示例一實現分析優化運行結果示例二實現代碼運行結果示例三實現代碼運行結果讀寫鎖示例實現代碼注意分析運行結果附言實現運行結果運行結果個人心得引言 項目中使用多線程,會遇到兩種問題,一種是對共享資源的訪問時需要…

關于運行flutter app 運行到模擬器出現異常提示

Exception: Gradle task assembleDebug failed with exit code 1 解決方案&#xff1a; 1.講當前文件的distributionUrl值改為 https://mirrors.cloud.tencent.com/gradle/gradle-7.4-all.zip

Redis 學習筆記 3:黑馬點評

Redis 學習筆記 3&#xff1a;黑馬點評 準備工作 需要先導入項目相關資源&#xff1a; 數據庫文件 hmdp.sql后端代碼 hm-dianping.zip包括前端代碼的 Nginx 啟動后端代碼和 Nginx。 短信登錄 發送驗證碼 PostMapping("code") public Result sendCode(RequestP…